Я пишу алгоритм, который делит число с плавающей запятой на 2.
В случае уже нормализованных чисел (биты экспоненты> 0), я думаю, что процесс довольно прост. Я думаю, что просто уменьшить значение поля экспоненты на единицу, а затем вставить это значение обратно - правильный подход.
У меня возникают проблемы с тем, как обработать число с плавающей запятой, которое уже денормализовано (все экспонентные биты равны 0).
Я понимаю, что такое денормализованное число, и полагаю, что я в целом понимаю, что значит разделить их. Я запускаю алгоритм, который пишу через другую программу, и вот одно сообщение, которое меня смущает:
Передача значения 0x7fffff в функцию возвращает 3fffff. Функция должна возвращать 0x400000.
Я не очень понимаю, что здесь происходит, и почему это должно возвращать указанное значение. Кто-нибудь может попытаться объяснить это и почему он должен возвращать это значение?
Мой первоначальный подход к обработке денормализованного числа состоял в том, чтобы сдвинуть биты дроби вправо на единицу (деление на 2), и это, похоже, не является желательной процедурой.
Вот что у меня есть:
unsigned float_half(unsigned uf) {
unsigned exp = uf & (0x7F800000);
unsigned sign = uf & (0x80000000);
unsigned fract = uf & (0x007FFFFF);
// Check for NaN or infinity
if(exp == 0x7F800000) {
return uf;
}
// Check for denormalized numbers
if(exp == 0x00000000) {
// Need to do something here, not really sure...
return sign | exp | fract;
}
// Check for exponent of 1 (going to a denormalized number changes things)
if(exp == 0x00800000) {
fract = (0x00FFFFFF & uf) >> 1;
return fract | sign;
}
exp--;
exp = exp & (0x7F800000);
return sign | exp | fract;
}