浮点数是如何以hex表示的?

我正在从iPhone传输数据到从设备,其中传输需要16位数据值。 现在我有一个我需要传输的浮点值,但是我怎么知道它有多大,它是如何用hex表示的?

需要hex表示,因为我可能需要切换低位和高位半字节。

如果您想了解详细信息,请在Web上查找IEEE浮点标准 。 但要以hex表示,只需生成数字,获取单个字节,并生成其hex表示。 您需要知道的两件事是值的长度(例如, sizeof(double) )以及它是否存储为“big-endian”或“little-endian”。 iOS设备始终是“小端”,这意味着值的最低有效字节具有最低的内存地址。

获取字节的直接方法是创建floatdouble的C union以及unsigned char的适当长度数组。 将float值存储到union中,然后检索unsigned char字节以转换为hex。 您还可以使用适当指针类型的强制转换来执行此“锯齿”。

 union { float f; double d; unsigned char c[8]; } foo; foo.d = 3.14156; for(int i=0;i<8;i++) printf("%02X",foo.c[i]); 

对于不能选择联合和别名的Java用户 ,Float和Double上有这些类方法:

 Float.floatToRawIntBits(floatValue) Double.doubleToRawLongBits(doubleValue) 

和他们的逆转

 Float.intBitsToDouble(intValue) Double.longBitsToDouble(longValue) 

请注意,这些进行类似转换的转换(4.1 float 不会转换为4 int,例如),而是将位模式从float转换为整数格式。

在iOS设备上,浮点数存储有符号位,偏置指数和编码的有效位数。

对于32位浮点数( float ),指数为8位,偏置为127,编码的有效位数为23位。 对于64位浮点数( double精度),指数为11位,偏置为1023,编码的有效位数为52位。

以下描述了32位浮点数。 它来自记忆; 我没有仔细检查过它。 64位浮点数类似。

考虑浮点数F.用unsigned int E = (union { float f; unsigned int u; }) { F }.u;定义E unsigned int E = (union { float f; unsigned int u; }) { F }.u; 。 在iOS设备(以及许多其他常见计算机)上,E将包含F的编码,即表示它的位。

我们是E>>31 。 这是标志位。 如果F为正(包括+0)则为0,如果F为负(包括-0)则为1。

设e为E>>23 & 0xff 。 这是有偏见的指数。 无偏(实际)指数是e-127。

设f为E & 0x7fffff 。 那是编码的有效数字。 如果0 f 2 ,其中f是以二进制数字写入的f的23位。 因此,如果f为0x600000,则f为二进制,1100000000000000000000 2 ,因此实际有效数为1.1100000000000000000000 2 ,即1.11 2 ,即1 + 1/2 + 1/4 = 1.75。

同时,此编码表示的数字为(-1) s •2 e-127 •1。 f 2 。 因此,对于编码0x40600000,s为0,e为0x100 = 128,f为1100000000000000000000 2 ,因此值为(-1) 0 •2 128-127 •1.75 = 1•2•1.75 = 3.5。

有一些特殊情况。 如果e为0,则实际有效数为0. f 2而不是1. f 2 。 也就是说,隐式1变为0.注意,如果f为零,则表示的值为0.符号仍然有意义,浮点数为零; +0和-0的行为略有不同。

如果e为255且f为0,则表示的值为无穷大,无论是+无穷大还是无穷大,具体取决于符号。

如果e为255且f不为0,则该值为具有某些实现定义语义的NaN。

要对浮点值进行编码,请确定符号,然后计算不大于值大小的2的最大幂。 两个力量给你无偏见的指数。 然后你将值除以2的幂并将其四舍五入以适合有效数字,这样就可以得到有效数字。 有一些特殊情况,当舍入将有效数字推到2(你必须调整指数),当指数大到足以下溢或小到足以下溢到非正规范围时(低于偏差指数为1的范围或更大)。