IEEE - 754 - 查找signbit,exponent,frac,normalized等

时间:2010-01-11 21:19:06

标签: c++ c ieee-754

我将8位十六进制数作为IEEE 754位浮点数 我想打印有关该数字的信息(signbit,expbits,fractbits,normalized, 非规范化,无穷大,零,NAN)浮点应该是单一的。

我读到了位移,我想这就是我想要做的事情。但是,我并非100%肯定。我知道符号位位于数字的最左侧位置。表示正面或负面。我将它移动多少才能找到每个?我只是继续转移它找到每一个?有人可以解释我是如何找到每个人的吗?

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

signbit应为零

expbits应为128

fracbits应为0x00000000 我想......

如果是这样,我如何在换班后测试它?

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

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

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

这就是它的作用..

7 个答案:

答案 0 :(得分:13)

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

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

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

除了你已经考虑过的一点点,还有一些库函数允许你剖析和缩放浮点数。

如果您手头有floatdouble,则可以使用std::frexp()来确定其有效数(或尾数)和指数。指数将是整数,但有效数将是0.5到1或0之间的实数。

答案 3 :(得分:1)

&安培;在两个值之间进行逐位操作。如果其中一个值是常数&amp;有一些有用的属性。

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

正如你在真值表中看到的那样,前两行显示如果A = 0,A&amp; B = 0.因此,将掩码中的零置于某个位置会产生清除该位的效果。

最后两行显示如果A = 1,A&amp; 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才能提取符号位)

答案 4 :(得分:0)

冰冻问道:

  

有人可以解释这里发生了什么吗?我们在哪里提出&amp;数字?

&amp; operator是按位AND运算符。十六进制数是位掩码,通过应用&amp;使用适当的掩码运算符,可以隔离您感兴趣的位。

答案 5 :(得分:0)

@vicatcu,或其他任何人

icelated ..

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

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

答案 6 :(得分:0)

代码修订:

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

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;
}