有没有更安全的方法来使用联合在整数和浮点数之间进行转换? [英] Is there a safer way to use unions to convert between integer and floating-point numbers?

查看:26
本文介绍了有没有更安全的方法来使用联合在整数和浮点数之间进行转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 Rust 编写一个 VM,我有 C 和 C++ 背景.我需要类似联合的功能,因为在 VM 堆栈上,我可以存储 intfloat.

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.

在 C 中我有一个联合:

In C I had a union:

union stack_record_t {
    int i;
    float f;
};

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

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.

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

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?

推荐答案

您可以使用 f32::from_bitsto_bits 安全地将 u32 的原始位重新解释为 f32,反之亦然.这是一个免费"的转换–它编译为无代码(打开优化).¹要在 u32i32 之间进行转换,您可以使用 as 强制转换,这在用于更改签名时同样是免费的.

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.

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

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();
    }
}

比较生成的代码.

¹这些函数在内部使用 transmute,就像使用联合一样重新解释位.所以当它们被优化器内联时,生成的代码是相同的.

¹ 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.

这篇关于有没有更安全的方法来使用联合在整数和浮点数之间进行转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆