#include <stdlib.h>
#include <stdio.h>
#include <float.h>
#include <math.h>
void PrintBytes(const float value)
{
const char* const byte = (const char*)&value ;
for(size_t i = 0 ; i < sizeof(value) ; i++)
{
printf("%02hhx" , byte[i]);
}
}
int main(void)
{
float value = FLT_MIN;
while(1)
{
printf("%e %d " , value , isnormal(value));
PrintBytes(value);
puts("");
if(!isnormal(value))
{
break;
}
value /= 2.0F;
}
return 0;
}
Выход:Почему isnormal() говорит, что это нормально, когда это не так?
1.175494e-038 1 00008000
5.877472e-039 1 00004000
2.938736e-039 1 00002000
1.469368e-039 1 00001000
7.346840e-040 1 00000800
3.673420e-040 1 00000400
1.836710e-040 1 00000200
9.183550e-041 1 00000100
4.591775e-041 1 00800000
2.295887e-041 1 00400000
1.147944e-041 1 00200000
5.739719e-042 1 00100000
2.869859e-042 1 00080000
1.434930e-042 1 00040000
7.174648e-043 1 00020000
3.587324e-043 1 00010000
1.793662e-043 1 80000000
8.968310e-044 1 40000000
4.484155e-044 1 20000000
2.242078e-044 1 10000000
1.121039e-044 1 08000000
5.605194e-045 1 04000000
2.802597e-045 1 02000000
1.401298e-045 1 01000000
0.000000e+000 0 00000000
Очевидно, что второе значение 5.877472e-039
субнормальна, так как его показатель становится 0, 00004000
.
Ideone производит правильный результат:
1.175494e-38 1 00008000
5.877472e-39 0 00004000
Я компиляции моего кода с помощью GCC (MinGW-w64) на Windows.
В [ 'isnormal'] (http://en.cppreference.com/w/c/numeric/math/isnormal) определяется как * macro *, что делает ваш макрос в вашей реализации, который, кажется, не присутствует? Возможно, стоит посмотреть. – WhozCraig
Просто догадаться: неверно ли преобразован макрос в аргумент типа double? –
@JamesMcNellis судя по результату, это тоже будет моя интерпретация. – WhozCraig