我有一个浮点数的一小部分(例如-10.5中的5)。这是一个角色,因为我从输入中提取了它。如何将该字符转换为该浮点数的二进制小数部分? (我正在构建一个浮点输入 - > HEX输出在32位IEEE784中,我已经提取了尾数的符号,指数和整数部分的二进制表示。)
我一直在考虑实现将分数乘以2并取余数的算法,然后重复直到填充尾数,但我不允许在赋值中使用任何浮点运算。
实施例: 用户输入-10.5。程序需要取数字的一小部分(即5)并将其转换为二进制格式(即1(.1))
编辑:我受到16位寄存器大小的限制,因此我需要一个解决方案来操作数字> 2 ^ 16-1。
答案 0 :(得分:5)
你基本上有正确的想法。只需加倍小数部分,进位就成了数字。我们尝试将.7
转换为二进制作为示例(.5
太简单了)
NUMBER REMAINDER CARRY
.7 --- .
1.4 .4 1
.8 .8 0
1.6 .6 1
1.2 .2 1
.4 .4 0
.8 .8 0
1.6 .6 1
1.2 .2 1
&ct.
二进制文件中的.7
为.101100110...
。 10.7
只是1010.101100110...
一旦余数变为0
,或者由于IEEE浮点精度的限制,总表示变为24位长,就可以停止转换为二进制。
请注意,十进制本身纯粹是装饰性的,你不是在这里使用浮点数。
NUMBER %10 /10
7 --- .
14 4 1
8 8 0
16 6 1
12 2 1
4 4 0
8 8 0
16 6 1
12 2 1
&ct.
如果是.07
,您将代表余数并分别按%100
和/100
进行。对于.007
,您可以使用%1000
和/1000
。
答案 1 :(得分:2)
在IEEE-754意义上,对于总数的上下文之外的浮点数的小数部分没有明确定义的含义。区分值10.5
和值10.0
的位是整个表示的较小子集,而不是将值0.0
与值0.5
区分开的位。当谈到IEEE-754数字表示的“分数”部分时,通常会讨论尾数的所有位;用于IEEE 754单精度二进制格式,即24位,包括一个隐含位,无论数字的大小如何。
更新/修订:
根据澄清问题的更新,我已经取代了之前的大部分答案,该答案解决了以编程方式提取float
或double
的位的问题,而不是转换小数位 - 将 text 表示格式化为IEEE-754格式表示的位。解析文本是一个棘手的问题,正如我在这个答案的原始版本中所说的那样。
但我仍然重申,我认为将尾数分成不同的部分是错误的。它没有提供我能看到的特别优势,但它引入了以后正确重新组合的问题。
这是解决整体问题的可行方法:
根据是否存在负号确定输入数字的符号。
形成输入数字绝对值的bignum表示。例如,基数1,000,000,000表示,存储在uint32_t
数组中。只要基数是10的幂,就可以直接将十进制格式的输入数解析为这样的表示,并且不会引入舍入误差。
使用2的适当幂来缩放bignum表示,以获得2 23 和2 24 之间的缩放值 - 1.这只能用于整数运算。请注意,您可能需要缩放 down 而不是向上。无论哪种方式,这种缩放可以仅通过整数运算来执行。记住使用两个幂(s
)作为比例因子(即比例因子的基数2对数,而不是比例因子本身;这可以很容易地从算法中得出,而无需计算需要超越功能)。
舍入到单位精度。
然后你得到了步骤1中的符号位,尾数/有效数的位作为bignum的剩余有效位(请记住最重要的位是隐式的,不是显式的,在最终的IEEE格式中),并且指数为23 - s
。
同样请注意,这种方法可以非常自然地扩展到科学记数法。