Is there a safer way to use unions to convert between integer and floating-point numbers?

对着背影说爱祢 提交于 2021-01-28 03:43:33

问题


I´m writing a VM in Rust and I have a C and C++ background. I need union-like functionality because on the VM stack I can either store an int or a float.

In C I had a union:

union stack_record_t {
    int i;
    float f;
};

I can use the record as int or as float with zero runtime overhead. I have a static bytecode analyzer which will find type errors before the bytecode executes, so I don't have to store a flag alongside the record.

I don´t know if it is a good idea to use unions in Rust because they are unsafe. Is there any safe way to do this in Rust - also with zero cost? Should I just use the unsafe Rust unions?


回答1:


You can use f32::from_bits and to_bits to safely reinterpret the raw bits of a u32 as an f32 and vice versa. This is a "free" conversion – it compiles to no code (with optimizations turned on).¹ To convert between u32 and i32 you can use as casts, which are likewise free when used to change signedness.

It seems to me that u32 is the common denominator here, so you might consider making a struct that contains a u32 and exposes methods to get or set the appropriate type:

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.

See Also

  • Is it possible to write Quake's fast InvSqrt() function in Rust?
  • Is transmuting bytes to a float safe or might it produce undefined behavior?
  • Is casting between integers expensive?

¹ These functions use transmute internally, which reinterprets the bits just as using a union would. So when they are inlined by the optimizer the generated code is the same.



来源:https://stackoverflow.com/questions/60930777/is-there-a-safer-way-to-use-unions-to-convert-between-integer-and-floating-point

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!