有没有更安全的方法来使用联合在整数和浮点数之间进行转换? [英] Is there a safer way to use unions to convert between integer and floating-point numbers?
问题描述
我正在用 Rust 编写一个 VM,我有 C 和 C++ 背景.我需要类似联合的功能,因为在 VM 堆栈上,我可以存储 int
或 float
.
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;
};
我可以将记录作为 int
或 float
使用,运行时开销为零.我有一个静态字节码分析器,它会在字节码执行之前发现类型错误,所以我不必在记录旁边存储标志.
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_bits
和 to_bits
安全地将 u32
的原始位重新解释为 f32
,反之亦然.这是一个免费"的转换–它编译为无代码(打开优化).¹要在 u32
和 i32
之间进行转换,您可以使用 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屋!