按位浮点到 Int
Posted
技术标签:
【中文标题】按位浮点到 Int【英文标题】:Bitwise Float To Int 【发布时间】:2011-09-13 03:49:42 【问题描述】:我正在尝试找出算法,但我从谷歌得到的只是通过强制转换来实现。我需要知道细节。
那么如果我们有一个浮点 x 并且想要返回它的二进制表示,我们需要做什么?
我知道如果浮点数为 NaN 或无穷大,我们需要返回浮点数,否则步骤是什么?
编辑
该函数接受一个无符号整数,就像它是一个浮点数一样使用,然后返回数字代表的整数。我不能使用强制转换,只能使用条件和位运算符。
【问题讨论】:
“二进制表示”是什么意思?像 2.25 写成 10.01,还是浮点数的内部表示?内部表示通常采用 IEEE 格式,即值为 1.[mantissa]^(exponent),并且仅存储尾数和指数。您可以通过将内存复制到 int(或使用联合)并打印 int 来获得实际的 1 和 0。 @Adam,这可能只是您的一个小术语错误,但是将float
转换为 int
“只是”会截断数字的实部。您需要一些(相当简洁的)指针魔术来获得浮点数的位模式。我同意其他一切。
见***.com/questions/2376915/…
关于您的编辑... 这并不总是可能的,因为浮点数可能不是整数。你能澄清一下吗?
如果它不是整数,我假设它是 NaN 或无穷大。在那种情况下,我会返回一个特殊的序列。
【参考方案1】:
或者,使用联合:
typedef union
float f_;
int i_;
FloatBits;
FloatBits fb;
fb.f_ = 1.5;
然后fb.i_
包含映射到int
的浮点数以允许提取位。同样,关于类型大小的常见假设 - 您可以使用 sizeof
验证这些。
使用这种方法,您可以直接设置fb.i_
中的位,然后将它们映射回float
。
【讨论】:
我不能使用语言结构。我可能需要一个while循环或其他东西,但无法弄清楚...... 尽管大多数编译器都按照您的描述进行操作,但这种访问在技术上是 undefined behavior。 @Mark Elliot:在标准的最新版本中,这不是未定义的行为,而是给出了实现定义的值。这是获取浮点数位模式的推荐方法。另一方面,通过指针转换实现相同的技巧在技术上仍然是错误的。 @Dietrich Epp。感谢您的注意。我怀疑这个,谢谢你的确认。定义的实现就是我们所追求的。【参考方案2】:c
编程语言中的float
数字跟在the IEEE Standard for Floating-Point Arithmetic (IEEE 754) 后面。
您可以使用代码将float
转换为int
int i = *(int *)&f; // f is the float variable you want to convert
然后根据 IEEE 754 标准自己解读int
。
【讨论】:
C 没有指定浮点格式,这取决于平台,尽管实际上几乎所有现代平台都使用 IEEE754。 (more details) 不能使用显式转换,输入是一个无符号整数,可以被视为浮点数。 @Jace 然后自己按照标准转换一下。 :-) 你应该说服自己你可以通过条件语句和位操作来实现它。 这违反了严格的别名,不推荐。请改用联合。【参考方案3】:要测试 32 位值是否表示 NaN(如果它是浮点数),您可以检查其无符号值是否大于无穷大的表示。
int n =
if((n & 0x7FFFFFFF) > 0x7f800000) // is NaN
需要删除符号,因为 NaN 可以将负号位设置为 1(尽管 NaN 不是正数或负数)
如果你想知道一个浮点数是否为 NAN,你可以使用
float f = NAN
if (f != f) // is NAN
与 Infinity 比较
float f = INFINITY;
if (f == INFINITY)
【讨论】:
请注意,编译器“可以”优化f != f
。
@Matthias 仅当对于他们的目标,f != f
对于浮点 f
可以具有的所有值都是 false。对于声称提供 IEEE 754 算术(大多数)的编译器来说,情况并非如此,尽管gcc -ffast-math
是这种情况(它不声称提供 IEEE 754 算术)。
@PascalCuoq idd。对于 msvc++ /fp:fast。以上是关于按位浮点到 Int的主要内容,如果未能解决你的问题,请参考以下文章
关于金额,重量等浮点数的数据库字段设计(用Int,Long代替浮点数计算)