有没有更安全的方法使用联合在整数和浮点数之间转换?

我正在Rust中编写VM,并且具有C和C ++背景。我需要类似工会的功能,因为在VM堆栈上,我可以存储intfloat

在C语言中我有一个联合:

union stack_record_t {
    int i;
    float f;
};

我可以将记录用作intfloat,且运行时开销为零。我有一个静态字节码分析器,它将在字节码执行之前发现类型错误,因此我不必在记录旁边存储标志。

我不知道在Rust中使用联合是不是一个好主意,因为它们是不安全的。在Rust中,有没有安全的方法可以做到这一点-而且成本也为零? 我应该只使用不安全的Rust联合吗?

a793358269 回答:有没有更安全的方法使用联合在整数和浮点数之间转换?

您可以使用f32::from_bitsto_bitsu32的原始位安全地重新解释为f32,反之亦然。这是一次“免费”转换-编译为无代码(启用了优化功能)。¹要在u32i32之间进行转换,您可以使用as强制转换,当用来更改签名。

在我看来u32是这里的公分母,因此您可以考虑制作一个包含struct并公开用于获取或设置适当类型的方法的u32

pub struct Record(u32);

impl Record {
    fn get_int(&self) -> i32 {
        self.0 as _
    }

    fn get_float(&self) -> f32 {
        f32::from_bits(self.0)
    }

    fn set_int(&mut self,value: i32) {
        self.0 = value as _;
    }

    fn set_float(&mut self,value: f32) {
        self.0 = value.to_bits();
    }
}

Compare the generated code.

另请参见


¹这些函数在内部使用transmute,就像使用并集一样重新解释位。因此,当优化程序内联它们时,生成的代码是相同的。

本文链接:https://www.f2er.com/2551330.html

大家都在问