IEEE - 754 -查找符号位、指数、frac、归一化等

vof42yt1  于 2023-03-28  发布在  其他
关注(0)|答案(8)|浏览(150)

我将一个8位十六进制数作为IEEE 754位浮点数,我想打印有关该数的信息(符号位、扩展位、分形位、规格化、反规格化、无穷大、零、NAN)浮点数应为单个。
我读了位移位,我想这是我应该怎么做?.然而,我不是100%肯定.我明白,符号位是在数字的最左边的位置.这表明积极或消极.我移动多少找到每一个?我只是不断移动它找到每一个?有人能解释我是如何找到每一个?
我会移位1来找到符号位吗?我会移位8来得到指数吗?我会移位23来得到压裂吗?
符号位应为零
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

这就是它在做什么。

lymgl2op

lymgl2op1#

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

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

如果指数为255,则数字为+-无穷大或NaN,具体取决于尾数是否为零(0表示无穷大)。如果指数为零,则数字为+-零(如果尾数为零)或尾数为实际的未归一化分数值。
如果指数是任何其他的,在分数的顶部有一个隐藏的1位,使其成为24位。在这种情况下,实际的指数可以通过从指数中减去127来计算,因此它在-127到+127的范围内,2的幂指数。

ktecyv1j

ktecyv1j2#

除了您已经在考虑的一些小问题之外,还有一些库函数允许您分析和缩放浮点数。
如果你有一个floatdouble,你可以用std::frexp()来确定它的有效数(或尾数)和指数。指数将是整数,但有效数将是0.5和1之间的实数或零。

noj0wjuj

noj0wjuj3#

要检查您的代码是否正确,请使用转换器小程序http://www.h-schmidt.net/FloatApplet/IEEE754.html
我发现小程序是有用的检查一些值。

xtfmy6hx

xtfmy6hx4#

&在两个值之间进行逐位与运算。如果其中一个值是常量,&具有一些有用的属性。

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。因此,在掩码的某个位置放置1具有 * 传递 * 该位的效果。
因此,您可以使用常量掩码来清除已知字段之外的位。
你可以用OR(|)和XOR(k),并得出结论:|具有 * 设置 * 掩码为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)。现在如果你想知道字段的值,您需要将结果向右移动所需的量。所需的量为(通常)字段的最低有效位的零索引位位置。
顺便说一下,当向右移位时,你必须小心。我们可以在这里摆脱它,因为我们知道我们的掩码在最高有效位有一个零,但如果不是这样,我们将明智地在向右移位之前将结果转换为无符号值。如果你不这样做,你会得到符号扩展。

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来提取符号位)

hof1towb

hof1towb5#

冰乐问道:
有人能解释一下这里发生了什么吗?我们在哪里得到的&数字?
&运算符是按位AND运算符。十六进制数是位掩码,通过将&运算符与适当的掩码一起应用,您可以隔离您感兴趣的位。

eulz3vhy

eulz3vhy6#

@vicatcu,或其他任何人这是
icelated..
IEEE单精度浮点标准表示法需要一个32位字,它可以表示为从0到31,从左到右编号。
因此,为了提取符号位,我们使用适当的掩码并移位31以获得结尾处的符号?此外还获得指数的值。由于其长度为8位-我们移位31 - 8(23)把它移到末尾?如果为真,那么尾数不需要移位?此外,为了提取值,我们使用掩码。这部分让我困惑。我认为掩码是十六进制等价物。我们如何得出十六进制数?例如:int exponent =(HexNumber & 0x7f800000)Thank You - I think I am getting this....

dw1jzc5e

dw1jzc5e7#

代码修订:

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

wvmv3b1j8#

既然你提到了C++,我认为最好的方法是使用标准库提供的函数,而不是试图猜测。

  • std::isnormal(value)--如果为true,则浮点数被视为正常
  • std::isnan(value)--浮点不是数字(NaN)
  • std::isunordered(value)--无法比较浮点数并返回有意义的结果
  • std::signbit(value)--提取浮点数的符号
  • std::isinf(value)--浮点为+inf或-inf
  • std::isfinite(value)--浮点数是一个有效的数字(不是NaN也不是+inf/-inf)
  • std::fpclassify(value)--如果您对类型感兴趣,而不是调用多个函数(* 替换 * isinf() + isnan() + isfinite()
  • std::frexp(value)--返回尾数和指数(如num × 2^exp == value
  • std::ldexp(value, num)--与std::frexp()相反,用于在可能的调整后“改革”浮点数
  • std::copysign(a, b)--返回带有符号'B'的'a'

一个很好的起点是standard library math header

相关问题