Библиотека C включает функцию, которая выполняет именно эту задачу, frexp
:
int expon;
float mant = frexpf(n, &expon);
printf("%g = %g * 2^%d\n", n, mant, expon);
Другой способ сделать это с помощью log2f
и exp2f
:
if (n == 0) {
mant = 0;
expon = 0;
} else {
expon = floorf(log2f(fabsf(n)));
mant = n * exp2f(-expon);
}
Эти два метода, вероятно, дадут разные результаты для одних и тех же входных данных. Например, на моем компьютере метод frexpf
описывает 4 как 0,5 23, а метод log2f
описывает 4 как 1 22. Оба правильны с математической точки зрения. Кроме того, frexp
даст вам точные биты мантиссы, тогда как log2f
и exp2f
, вероятно, округлят последний бит или два.
Вы должны знать, что *(unsigned *)&n
и *(float *)&m
нарушают правило против "каламбура" и имеют неопределенное поведение. Если вы хотите получить целое число с тем же битовым представлением, что и число с плавающей запятой, или наоборот, используйте объединение:
union { uint32_t i; float f; } u;
u.f = n;
num = u.i;
(Примечание: такое использование союзов четко определено в C примерно с 2003 года, но из-за давней привычки комитета C++ не уделять достаточного внимания изменениям, происходящим в C, оно официально не определено в C++.)
Вы также должны знать, что числа с плавающей запятой IEEE используют «смещенные» показатели степени. Когда вы инициализируете поле мантиссы переменной float
, но оставляете ее поле экспоненты равным нулю, это дает вам представление числа с большим отрицательным показателем: другими словами, число настолько маленькое, что printf("%f", n)
напечатает его. как ноль. Всякий раз, когда printf("%f", variable)
печатает ноль, измените %f
на %g
или %a
и перезапустите программу, прежде чем предположить, что variable
на самом деле равно нулю.
person
zwol
schedule
12.04.2018
frexp
и т. д.. - person Oliver Charlesworth   schedule 12.04.2018float
, когда она соответствует 32-битномуint
? Не забудьте включить неявный (не сохраненный) старший1
бит мантиссы/мантиссы. - person Weather Vane   schedule 12.04.2018printf
? - person Weather Vane   schedule 12.04.2018