Есть ли более безопасный способ использования объединений для преобразования целых чисел в числа с плавающей запятой?
Я пишу виртуальную машину на Rust и имею опыт работы с C и C++. Мне нужна функция объединения, потому что в стеке виртуальных машин я могу хранитьint
или float
.
В CI был союз:
union stack_record_t {
int i;
float f;
};
Я могу использовать запись как int
или как float
с нулевыми накладными расходами времени выполнения. У меня есть статический анализатор байт-кода, который находит ошибки типа до выполнения байт-кода, поэтому мне не нужно хранить флаг рядом с записью.
Я не знаю, стоит ли использовать объединения в Rust, потому что они небезопасны. Есть ли безопасный способ сделать это в Rust - также с нулевой стоимостью? Должен ли я просто использовать небезопасные профсоюзы Rust?
1 ответ
Ты можешь использовать f32::from_bits
а также to_bits
безопасно переосмыслить необработанные кусочки u32
как f32
и наоборот. Это "бесплатное" преобразование - оно не компилируется в код (с включенной оптимизацией). Для преобразования междуu32
а также i32
вы можете использовать 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();
}
}
Смотрите также
- Можно ли написать быструю функцию InvSqrt() Quake на Rust?
- Безопасно ли преобразование байтов в число с плавающей запятой или это может привести к неопределенному поведению?
- Дорогой ли перевод между целыми числами?
¹ Эти функции используют transmute
внутренне, который интерпретирует биты так же, как при использовании объединения. Поэтому, когда они встроены оптимизатором, сгенерированный код будет таким же.