IEEE – 754 – 找到signbit,exponent,frac,normalized等

我接收一个8位hex数作为IEEE 754位浮点数,我想打印有关该数字的信息(signbit,expbits,fractbits,normalized,denormalized,infinity,zero,NAN)浮点应该是单个。

我读了一下比特移位,我想这就是我想这样做的原因吗? 但是,我不是百分百肯定。 我知道符号位位于数字的最左侧位置。 表示正面或负面。 我将它移动多少才能找到每个? 我只是继续转移它找到每一个? 谁能解释我是如何找到每一个人的?

我会换1来找到标志吗? 我会换8来得到指数吗? 我会换23来获得压裂吗?

signbit应为零

expbits应该是128

fracbits应该是0x00000000我认为……

如果是这样我怎么在换class后测试呢?

这就是我到目前为止所拥有的

#include  #include  int main(int argc, char *argv[]) { short wordOrder = 0x0100; int HexNumber; printf("Hex IEEE - 754\n"); if(wordOrder == 0x0100) { printf("\nbyte order: big-endian\n"); } else { printf("byte order: little-endian\n"); } printf("\n>"); scanf("%x", &HexNumber); printf("\n%#x",HexNumber); return 0; } 

我的输入(scanf)我想要的方式..

 >40000000 0x40000000 

它正在做什么..

对于单精度数,高位是符号,接下来的8位是指数,剩下的23位是尾数。 所以…

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

如果指数为255,则数字为+ – 无穷大或NaN,具体取决于尾数是否为零(0表示无穷大)。 如果指数为零,则以太数字为+ – 零(如果尾数为零)或者尾数是实际的非标准化小数值。

如果指数是其他任何东西,则在分数的顶部有一个隐藏的位,使其为24位。 在这种情况下,可以通过从指数中减去127来计算实际指数,使得它在-127到+127的范围内,两个指数的幂。

要检查您的代码是否正确,请参阅转换器小程序http://www.h-schmidt.net/FloatApplet/IEEE754.html

我发现Applet对于检查一些值非常有用。

&在两个值之间进行逐位操作。 如果其中一个值是常量并具有一些有用的属性。

  A | B | A & B ---+---+------- 0 | 0 | 0 0 | 1 | 0 ---+---+------- 1 | 0 | 0 1 | 1 | 1 

正如您在真值表中看到的那样,前两行显示如果A = 0,则A和B = 0.因此,在某个位置将掩码置于零中具有清除该位的效果。

最后两行显示如果A = 1,A&B = B.因此,在某个位置将掩码放在掩码中具有传递该位的效果。

因此,您可以使用常量掩码清除已知字段之外的位。

您可以使用OR(|)和XOR(^)执行相同的练习,并得出与|一起使用的蒙版 具有设置掩码为1的值的位的效果。^具有切换掩码为1的值的位的效果。

/ *回应评论* /

它不是一个指数位,它是一个8位长的指数字段。 所以,如果你按如下方式构建你的面具:

 0111 1111 1000 0000 0000 0000 0000 0000 (mask === 0x7F800000) 1011 1010 0101 0110 0110 1010 1001 1010 (value) ------------------------------------------------- 0011 1010 0000 0000 0000 0000 0000 0000 (result) 

您可以在此处看到,此操作遗留的所有内容都是组成指数字段的位(即01110100)。 现在,如果您想知道该字段的值,则需要将结果向右移动所需的数量。 所需的量(通常)是字段的最低有效位的零索引位位置。 对于指数字段,所需的移位量为23。

另一方面,向右移动时必须小心。 我们可以在这里使用它,因为我们知道我们的掩码在最重要的位中有一个零,但如果不是这种情况,我们最好将结果转换为无符号值,然后再向右移动。 如果你不这样做,你会得到签名扩展。

 int8_t exponent = ((uint32_t) (value & 0x7F800000)) >> 23; // the cast is not necessary in this case because the mask has a 0 in the msb 

如果你想提取符号位,这个演员阵容变得很重要:

 int8_t sign = ((uint32_t) (value & 0x80000000)) >> 31; 

(我不知道你在哪里得到你必须换8来提取符号位的概念)

除了你已经考虑过的一点点,你可以使用一些库函数来解析和缩放浮点数。

如果你有一个floatdouble ,你可以使用std::frexp()来确定它的有效数(或尾数)和指数。 指数将是整数,但有效数将是0.5和1之间的实数或零。

冰冻问道:

有人能解释一下这里发生了什么吗? 我们在哪里提出&号码?

&运算符是按位AND运算符。 hex数字是位掩码,通过使用适当的掩码应用&运算符,您可以隔离您感兴趣的位。

@vicatcu,或其他任何人

icelated ..

IEEE单精度浮点标准表示需要32位字,其可以表示为从0到31编号,从左到右。 第一位是符号位,后8位是指数位,最后23位是分数。

因此,为了提取符号位,我们使用适当的掩码并移动31以获得最后的符号? 除了获得指数的值。 因为它的长度为8位 – 我们将31 – 8(23)移位到最后? 如果为真,那么尾数不需要移位? 另外,要提取值,我们使用掩码。 这部分让我很困惑。 我认为面具是hex等效的。 我们如何提出这个hex数? ex:int exponent =(HexNumber&0x7f800000)谢谢 – 我想我得到了这个….

代码修订:

 #include  #include  int main(int argc, char *argv[]) { int HexNumber; int a = 0x12345678; unsigned char *c = (unsigned char*)(&a); if (*c == 0x78) { printf("\nlittle-endian\n"); } else { printf("\nbig-endian\n"); } printf("\n>"); scanf("%x", &HexNumber); printf("\n%#x",HexNumber); bool negative = !!(HexNumber & 0x80000000); int exponent = (HexNumber & 0x7f800000) >> 23; int mantissa = (HexNumber & 0x007FFFFF); printf("\nsignBit %d,", negative); printf("expbits %d,", exponent); printf("fractbits %#x,", mantissa); return 0; }