【发布时间】:2014-05-28 17:09:36
【问题描述】:
我一直在研究将浮点数(浮点数和双精度数)转换为 IEEE 754 的方法,以便创建例程以有效地跨网络连接发送/接收信息。 (类似于 perl 的打包/解包功能。)我已经通过Lockless、technical-recipes.com、Bit Twiddling、Bitwizardry、Haskell.org (c++) 等方法了解了创建 IEEE 754 表示的方法,但我确实这样做了不明白为什么这些方法比仅仅使用联合来获得转换更快/更有效/更好?涉及整数/浮点数或长/双精度的联合转换似乎是让 C 处理符号、指数和尾数问题的更好方法,而不是手动使用移位和旋转进行。
例如,通过位旋转,您可以手动创建 IEEE 754 表示:
/* 23 bits of float fractional data */
#define I2F_FRAC_BITS 23
#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
/* Find the log base 2 of an integer (MSB) */
int
getmsb (uint32_t word)
{
int r;
#ifdef BUILD_64
union { uint32_t u[2]; double d; } t; // temp
t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] = 0x43300000;
t.u[__FLOAT_WORD_ORDER!=LITTLE_ENDIAN] = word;
t.d -= 4503599627370496.0;
r = (t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] >> 20) - 0x3FF;
#else
while (word >>= 1)
{
r++;
}
#endif /* BUILD_64 */
return r;
}
/* rotate to right */
inline uint32_t
rotr (uint32_t value, int shift)
{ return (value >> shift) | (value << (sizeof (value) * CHAR_BIT - shift)); }
/* unsigned to IEEE 754 */
uint32_t
u2ieee (uint32_t x)
{
uint32_t msb, exponent, fraction;
if (!x) return 0; /* Zero is special */
msb = getmsb (x); /* Get location of the most significant bit */
fraction = rotr (x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
exponent = (127 + msb) << I2F_FRAC_BITS;
return fraction + exponent;
}
/* signed int to IEEE 754 */
uint32_t i2ieee (int32_t x)
{
if (x < 0)
return u2ieee (-x) | 0x80000000;
return u2ieee (x);
}
此时您可以将其转换为十六进制或二进制字符串,将其放入一个数据包并在另一端反转该过程。 (注意,这只是针对 32 位的情况,64 位的数字也需要类似的功能。)为什么要这样?为什么不将浮点数或双精度数放在自动存储在 IEEE 754 表示中的联合中,然后简单地使用 int 或 long 表示?似乎所有情况都可以通过以下似乎不太容易出错的方式来处理:
union uif { int i; float f; };
union uid { long int i; double d; };
int
f2ieee (float f) {
union uif cvt;
cvt.f = f;
return cvt.i;
}
float
ieee32f (int i) {
union uif cvt;
cvt.i = i;
return cvt.f;
}
long
d2ieee64 (double d) {
union uid cvt;
cvt.d = d;
return cvt.i;
}
double
ieee64d (long int i) {
union uid cvt;
cvt.i = i;
return cvt.d;
}
所有这些都是很好的学习,但我错过了最重要的部分。为什么要以一种方式而不是另一种方式呢? 当简单地从联合中读取更不容易出错并且从表面上看似乎更有效时,手动转换提供了什么好处?专家怎么说?
【问题讨论】: