Я работаю над анализом файлов шрифтов OpenType, и мне нужно проанализировать (и записать) два вида чисел с фиксированной запятой:
- 16-битное фиксированное число со знаком с младшими 14 битами дроби(2.14)
- 32-разрядное число с фиксированной точкой со знаком (16.16)
Я предполагаю, что в конце оно должно быть приведено к / из f32
Спецификация OpenType описывает:
Формат F2DOT14 состоит из целого числа со знаком 2, дополнения 2 и дроби без знака.Чтобы вычислить фактическое значение, возьмите целое число и добавьте дробь.
Примеры значений 2.14:
Decimal Value Hex Value Integer Fraction
1.999939 0x7fff 1 16383/16384
1.75 0x7000 1 12288/16384
0.000061 0x0001 0 1/16384
0.0 0x0000 0 0/16384
-0.000061 0xffff -1 16383/16384
-2.0 0x8000 -2 0/16384
У меня есть решение, которое работает, но только для2.14 значения:
fn from(number: u16) -> f32 {
let mut int = (number >> 14) as f32;
if int > 1f32 {
int -= 4f32;
}
let frac = (number & 0b11_1111_1111_1111) as f32 / 16384 as f32;
int + frac
}
Поскольку целочисленное значение должно быть [-2, 2), я вычитаю 4, если проанализированное целое число больше 1, чтобы получить отрицательные числа.
Яищем способ сделать это для любого возможного разделения чисел с фиксированной точкой (например, 2.14
, 16.16
, 3.5
, 24.40
и т. д.) внутри стандартного диапазона целочисленных примитивных типов Rust (* 1034)*, u32
, u64
и т. Д.).