将分数部分转换为二进制

时间:2015-09-30 20:19:35

标签: c floating-point

我有一个浮点数的一小部分(例如-10.5中的5)。这是一个角色,因为我从输入中提取了它。如何将该字符转换为该浮点数的二进制小数部分? (我正在构建一个浮点输入 - > HEX输出在32位IEEE784中,我已经提取了尾数的符号,指数和整数部分的二进制表示。)

我一直在考虑实现将分数乘以2并取余数的算法,然后重复直到填充尾数,但我不允许在赋值中使用任何浮点运算。

实施例: 用户输入-10.5。程序需要取数字的一小部分(即5)并将其转换为二进制格式(即1(.1))

编辑:我受到16位寄存器大小的限制,因此我需要一个解决方案来操作数字> 2 ^ 16-1。

2 个答案:

答案 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位,包括一个隐含位,无论数字的大小如何。

更新/修订:

根据澄清问题的更新,我已经取代了之前的大部分答案,该答案解决了以编程方式提取floatdouble的位的问题,而不是转换小数位 - 将 text 表示格式化为IEEE-754格式表示的位。解析文本是一个棘手的问题,正如我在这个答案的原始版本中所说的那样。

但我仍然重申,我认为将尾数分成不同的部分是错误的。它没有提供我能看到的特别优势,但它引入了以后正确重新组合的问题。

这是解决整体问题的可行方法:

  1. 根据是否存在负号确定输入数字的符号。

  2. 形成输入数字绝对值的bignum表示。例如,基数1,000,000,000表示,存储在uint32_t数组中。只要基数是10的幂,就可以直接将十进制格式的输入数解析为这样的表示,并且不会引入舍入误差。

  3. 使用2的适当幂来缩放bignum表示,以获得2 23 和2 24 之间的缩放值 - 1.这只能用于整数运算。请注意,您可能需要缩放 down 而不是向上。无论哪种方式,这种缩放可以仅通过整数运算来执行。记住使用两个幂(s)作为比例因子(即比例因子的基数2对数,而不是比例因子本身;这可以很容易地从算法中得出,而无需计算需要超越功能)。

  4. 舍入到单位精度。

  5. 然后你得到了步骤1中的符号位,尾数/有效数的位作为bignum的剩余有效位(请记住最重要的位是隐式的,不是显式的,在最终的IEEE格式中),并且指数为23 - s

    同样请注意,这种方法可以非常自然地扩展到科学记数法。

相关问题