我将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
这就是它的作用..
答案 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)
除了你已经考虑过的一点点,还有一些库函数允许你剖析和缩放浮点数。
如果您手头有float
或double
,则可以使用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;
}