【发布时间】:2012-08-10 15:05:57
【问题描述】:
我正在将数据从 iPhone 传输到从设备,其中传输需要 16 位数据值。现在我有一个需要传输的浮点值,但我怎么知道它有多大,以及它是如何以十六进制表示的?
需要十六进制表示,因为我可能需要切换上下半字节。
【问题讨论】:
标签: ios floating-point type-conversion hex
我正在将数据从 iPhone 传输到从设备,其中传输需要 16 位数据值。现在我有一个需要传输的浮点值,但我怎么知道它有多大,以及它是如何以十六进制表示的?
需要十六进制表示,因为我可能需要切换上下半字节。
【问题讨论】:
标签: ios floating-point type-conversion hex
如果您想了解详情,请在网上查找IEEE floating-point standard。但是要以十六进制表示,只需生成数字,获取各个字节,然后生成它们的十六进制表示。您需要知道的两件事是值的长度(例如,sizeof(double))以及它是存储“big-endian”还是“little-endian”。 iOS 设备总是“小端”,这意味着值的最低有效字节具有最低的内存地址。
获取字节的直接方法是创建float 或double 的C union 和unsigned char 的适当长度数组。将浮点值存储到联合中,然后检索 unsigned char 字节以转换为十六进制。您还可以使用适当指针类型的强制转换来执行此“别名”。
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),而是将 位模式从浮点到整数格式不变。
【讨论】:
在 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。在 iOS 设备(以及许多其他普通计算机)上,E 将包含 F 的编码,即表示它的位。
让我们成为E>>31。它是符号位。如果 F 为正(包括 +0)则为 0,如果 F 为负(包括 -0)则为 1。
设 e 为 E>>23 & 0xff。那是有偏的指数。无偏(实际)指数是 e-127。
设 f 为 E & 0x7fffff。那是编码的有效数字。如果 0 f2,其中 f 是 f 的 23 位,写成二进制数字.因此,如果 f 为 0x600000,则 f 在二进制中为 11000000000000000000002,因此实际有效位为 1.110000000000000000000002,即 1.112 ,即 1+1/2+1/4 = 1.75。
这个编码表示的数字加起来是(-1)s•2e-127•1.f 2。所以,对于编码0x40600000,s为0,e为0x100 = 128,f为110000000000000000000002,所以值为(-1)0•2128-127•1.75 = 1•2•1.75 = 3.5。
有一些特殊情况。如果 e 为 0,则实际有效数字为 0.f2 而不是 1.f2。即隐含的 1 变为 0。注意如果 f 为零,则表示的值为 0。符号对于浮点零仍然有意义; +0 和 -0 的行为略有不同。
如果 e 为 255 且 f 为 0,则表示的值是无限的,可以是 +infinity 或 -infinity,具体取决于符号。
如果 e 为 255 且 f 不为 0,则该值为 NaN,具有一些实现定义的语义。
要对浮点值进行编码,您需要确定符号,然后计算不大于该值大小的 2 的最大幂。 2 的幂为您提供无偏指数。然后将值除以 2 的幂并将其四舍五入以适合有效数字,这就是有效数字。有一些特殊情况,当舍入将有效数推至 2(您必须调整指数)以及当指数大到足以下溢或小到足以下溢到非正规范围(低于偏置指数为 1 或更大)。
【讨论】: