C IEEE 754表示法

C IEEE 754表示法,c,floating-point,C,Floating Point,有人能检查一下我的程序并告诉我是否正确吗 我接受8位十六进制数字形式的用户输入。我想将这8位数字解释为IEEE 754 32位浮点数,并将打印出有关该数字的信息 以下是我的输出: IEEE 754 32-bit floating point byte order: little-endian >7fffffff 0x7FFFFFFF signBit 0, expbits 255, fractbits 0x007FFFFF normalized: exp = 128 SNaN &

有人能检查一下我的程序并告诉我是否正确吗

我接受8位十六进制数字形式的用户输入。我想将这8位数字解释为IEEE 754 32位浮点数,并将打印出有关该数字的信息

以下是我的输出:

IEEE 754 32-bit floating point

byte order: little-endian

>7fffffff

0x7FFFFFFF
signBit 0, expbits 255, fractbits 0x007FFFFF
normalized:   exp = 128
SNaN

>40000000

0x40000000
signBit 0, expbits 128, fractbits 0x00000000
normalized:   exp = 1

>0

0x00000000
signBit 0, expbits 0, fractbits 0x00000000
+zero
这是密码

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{


int HexNumber;
int tru_exp =0;
int stored_exp;
int negative;
int exponent;
int mantissa;

printf("IEEE 754 32-bit floating point");


int a = 0x12345678;
unsigned char *c = (unsigned char*)(&a);
if (*c == 0x78)
{
    printf("\nbyte order: little-endian\n");
}
else
{
    printf("\nbyte order: big-endian\n");
}

do{

printf("\n>");
scanf("%x", &HexNumber);

    printf("\n0x%08X",HexNumber);

negative = !!(HexNumber & 0x80000000);
exponent = (HexNumber & 0x7f800000) >> 23;
mantissa = (HexNumber & 0x007FFFFF);


printf("\nsignBit %d, ", negative);
printf("expbits %d, ", exponent);
printf("fractbits 0x%08X", mantissa);
//  "%#010x, ", mantissa);

if(exponent == 0)
{
    if(mantissa != 0)
    {
        printf("\ndenormalized  ");
    }
}
else{
    printf("\nnormalized:   ");
    tru_exp = exponent - 127;
    printf("exp = %d", tru_exp);
}

if(exponent == 0 && mantissa == 0 && negative == 1)
{

    printf("\n-zero");

}

if(exponent ==0 && mantissa == 0 && negative == 0)
{
 printf("\n+zero");
}



if(exponent == 255 && mantissa != 0 && negative == 1)
{

    printf("\nQNaN");

}

   if(exponent == 255 && mantissa != 0 && negative == 0)
{

    printf("\nSNaN");

}

if(exponent == 0xff && mantissa == 0 && negative == 1)
{
    printf("\n-infinity");
}

if(exponent == 0xff && mantissa == 0 && negative == 0)
{
    printf("\n+infinity");
}


    printf("\n");
}while(HexNumber != 0);



return 0;
  }
#包括
#包括
int main(int argc,char*argv[])
{
整数;
int tru_exp=0;
int存储单元exp;
int负数;
整数指数;
整数尾数;
printf(“IEEE 754 32位浮点”);
INTA=0x12345678;
无符号字符*c=(无符号字符*)(&a);
如果(*c==0x78)
{
printf(“\n字节顺序:小端\n”);
}
其他的
{
printf(“\n字节顺序:big-endian\n”);
}
做{
printf(“\n>”);
scanf(“%x”、&HexNumber);
printf(“\n0x%08X”,十六进制数);
负=!!(十六进制数&0x8000000);
指数=(十六进制数&0x7f800000)>>23;
尾数=(十六进制数&0x007FFFFF);
printf(“\nsignBit%d”,负片);
printf(“expbits%d,”,指数);
printf(“分数位数0x%08X”,尾数);
//“%#010x”,尾数);
如果(指数=0)
{
如果(尾数!=0)
{
printf(“\n标准化”);
}
}
否则{
printf(“\n标准化:”);
tru_exp=指数-127;
printf(“exp=%d”,tru_exp);
}
如果(指数==0&&尾数==0&&负==1)
{
printf(“\n-zero”);
}
如果(指数==0&&尾数==0&&负==0)
{
printf(“\n+0”);
}
如果(指数=255&&尾数!=0&&负==1)
{
printf(“\nQNaN”);
}
如果(指数=255&&尾数!=0&&负==0)
{
printf(“\nSNaN”);
}
如果(指数=0xff&&尾数=0&&负==1)
{
printf(“\n-无穷大”);
}
如果(指数=0xff&&尾数=0&&负==0)
{
printf(“\n+无穷大”);
}
printf(“\n”);
}while(HexNumber!=0);
返回0;
}

我不认为去规范化是正确的?

一般来说,你很接近。一些评论:

  • 0x7fffffff
    是一个安静的NaN,而不是信令NaN。符号位不确定NaN是否安静;相反,它是有效位(您称之为“尾数”的首选术语)字段的前导位<例如,code>0xffbfffff是一个信令NaN
编辑:interjay正确地指出,IEEE-754实际上并不需要这种编码;平台可以自由使用不同的编码来区分安静和信令NAN。但是,本标准建议:

应使用一个安静的NaN位字符串 用数据的第一位编码 尾随有效位字段T为1。 信号NaN位字符串应为 用数据的第一位编码 尾随有效位字段为0

  • 在IEEE-754术语中,无穷和N通常不被称为“正常数”

  • 您呼叫号码“非规范”的条件是正确的

  • 对于普通数字,报告有效位时最好添加隐式前导位。我个人可能会用C99十六进制表示法打印出来:
    0x40000000
    的有效位(添加隐式位后)为
    0x800000
    ,指数为
    1
    ,因此变成
    0x1.000000p1

  • 我相信一些年迈的PDP-11黑客会让你很难理解“big-endian”和“little-endian”不是唯一的两种可能性

编辑确定,在使用IEEE-754推荐编码的平台上检查qNaN的示例:

if (exponent == 0xff && mantissa & 0x00400000) printf("\nqNaN");

缩进是你的朋友…仅供参考此网站非常有用:+1。值得一提的是,基于有效位的第一位来区分qNan/sNan对于Intel和AMD处理器是正确的,但是在其他系统上可能会有所不同,因为标准中没有指定它。@interjay:感谢您捕捉到这一点!在大多数(并非所有)现代硬件上,当且仅当设置了
0x00400000
位时,NaN是安静的,并且在清除位时发出信号。您正在使用符号位(
0x8000000
)进行检查,但这样做是不对的。(请注意,标准并未明确规定安静型和信令型NAN之间的区别)那么,检查它们之间的条件是什么?我不明白你说的“0x00400000位已设置”是什么意思,我需要一些条件,比如:如果(指数==0&&尾数==0&&负==1)我明白:QNaN是一个NaN,最重要的分数位设置为1000000000,我只是不知道如何测试它。