代码之家  ›  专栏  ›  技术社区  ›  paxdiablo

如何打印IEEE754号码(不打印F)?

  •  5
  • paxdiablo  · 技术社区  · 14 年前

    为了这个问题的目的,我知道 有能力使用 printf 设施(不幸的是,我不能告诉你为什么,但现在让我们假设我知道我在做什么)。

    对于IEEE754单精度数字,有以下位:

    SEEE EEEE EFFF FFFF FFFF FFFF FFFF FFFF
    

    哪里 S 是标志, E 是指数和 F 是分数。

    印刷标志对于所有的箱子来说都相对容易,因为它能捕捉到所有的特殊箱子,比如 NaN ( E == 0xff, F != 0 ), Inf ( E == 0xff, F == 0 )以及 0 ( E == 0, F == 0 ,因为在这种情况下不使用指数偏差而被认为是特殊的)。

    我有两个问题。

    首先是如何最好地转换非标准化的数字(在 E == 0, F != 0 )变成标准化的数字(其中 1 <= E <= 0xfe )? 我怀疑这对于简化下一个问题的答案是必要的(但我可能是错的,所以请随意教育我)。

    第二个问题是如何打印出标准化的数字。我想用两种方式打印出来,指数 -3.74195E3 非指数型 3741.95 . 不过,只要把这两个数字并排看,只要移动小数点就可以很容易地把前者变成后者。所以让我们专注于指数形式。

    我模糊地记得很久以前我用过一种算法打印出π,在那里你用了一个不断减少的公式,并对可能性保持了一个上限和下限,当两个极限都一致时输出一个数字,并将计算值移动了10倍(所以当上限和下限 3.2364 3.1234 ,您可以输出 3 并在计算中进行调整)。

    但这是一个 长的 自从我这么做以来,我甚至不知道这是否是一个合适的方法。看起来是这样的,因为当通过小数部分时,每一位的值是前一位的一半( 1/2 , 1/4 , 1/8 等等)。

    我真的更喜欢 不得不跋涉而过 除非绝对必要,否则源代码,如果有人能帮上忙,我将永远感激。

    4 回复  |  直到 14 年前
        1
  •  3
  •   Rick Regan    14 年前

    如果希望每次转换都得到准确的结果,就必须使用任意精度的算术,如printf()实现中所做的那样。如果您想要得到“接近”的结果,可能只在最低有效数字上有所不同,那么一个非常简单的基于双精度的算法就足够了:对于整数部分,重复除以10并附加剩余数以形成十进制字符串(反向);对于小数部分,重复乘以10并减去关闭整数部分以形成十进制字符串。

    我最近写了一篇关于这种方法的文章: http://www.exploringbinary.com/quick-and-dirty-floating-point-to-decimal-conversion/ . 它不打印科学符号,但这应该是微不足道的补充。这个算法会打印出低于正常值的数字(我打印的数字准确无误,但你必须做更彻底的测试)。

        2
  •  1
  •   lijie    14 年前

    非规范化数字不能转换为同一浮点类型的规范化数字。等效规范化数的指数太小,无法用指数表示。

    要打印标准化的数字,我能想到的一个愚蠢的方法是重复乘以10(好吧,对于小数部分)。

        3
  •  0
  •   Ignacio Vazquez-Abrams    14 年前

    首先需要做的是使用对数将指数转换为十进制(因为这可能是您想要的输出)。取结果的小数,将尾数乘以该小数的exp10,然后将其转换为十进制字符。从这里开始,您只需要在适当的位置插入小数点,然后按现在的十进制指数移动。

        4
  •  0
  •   AProgrammer    14 年前

    斯蒂尔的一篇论文更详细地描述了一种算法,它似乎与你所概述的算法基于相同的原理。如果内存可用,则有时会强制使用无限精度算法。(我想是的 如何准确打印浮点数 但citeeser现在已经不在这里了,我无法确认,谷歌的结果也被20年后的一篇回顾性论文所污染。