【问题标题】:Computation with Floating Point Numbers: When to Round?浮点数计算:何时舍入?
【发布时间】:2015-08-13 00:16:47
【问题描述】:

我在 C 中使用浮点数执行一些计算。我正在专门处理我得到指数的最低单精度值的情况。

假设我的指数是 -126,我必须减少它。在这种情况下,我不能再低了,所以我需要右移一次尾数。我知道我应该得到一个计算的确切答案,然后 然后 回合(到指定的任何地方)。

我正在考虑做(让M 成为尾数):

M >>= 1;
//round mantissa
  1. 由于我将尾数向右移动,并且浮点左侧隐含 1,因此在移动后是否需要修改 M,如下所示:

    M |= (1 << 23)
    

    确保我在最高有效位中有一个 1?

  2. 在丢失一些信息后四舍五入似乎很奇怪,但这是标准/公认的做法吗?或者我应该通过使用更多位和然后四舍五入来计算完整结果?

【问题讨论】:

  • "左边有一个隐含的 1" 不同意:当 M == -126 时没有隐含的 1。 Ref
  • 查看您的代码会很有用。

标签: c floating-point rounding ieee-754


【解决方案1】:

对于浮点数,有“法线”和“反法线”。

对于“法线”,尾数隐含 1 位,值为 ( 1 + (mantissa &gt;&gt; mantissa_bits) ) &lt;&lt; (exponent_value - exponent_bias)

对于“反法线”,尾数没有隐含的 1 位,指数始终是它的最小值(或者比法线的最小值小 1),并且值为 (mantissa &gt;&gt; mantissa_bits) &lt;&lt; (0 - exponent_bias)mantissa &gt;&gt; (exponent_bias + mantissa_bits)

对于反法线,当您向右移动时,指数保持不变,而尾数移动。最低有效位将丢失,但用于对尾数进行舍入(根据舍入模式)。例如。 (假设四舍五入)1011001b &gt;&gt; 5 = 10.11001b = 11b1001001b &gt;&gt; 5 = 10.01001b = 10b

请注意,反法线很烦人,并且会采取影响性能的特殊情况处理;所以大多数现代 CPU 都有一个特殊的“反法线为零”模式(不符合 IEEE 标准),它只是用 +/- 0 替换任何反法线。

如果您在软件中执行此操作,则使用较大的浮点格式(精度更高)进行所有计算并忽略反法线(这会降低微小数字的精度)以最终得到相同的结果可能会更快精确度降低了很多头痛。如有必要,您可以在“较大且无反常态”和“较小且无反常态”格式之间进行转换。具体来说;我很想使用没有反规范的 64 位尾数和 32 位指数,并使用例程在这种内部格式之间转换为“32 位浮点数”和“64 位双精度数”。

【讨论】:

    猜你喜欢
    • 2019-03-27
    • 1970-01-01
    • 2015-09-02
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多