gpt4 book ai didi

math - 以安全的方式将 64 位 IEEE 双倍截断为 61 位

转载 作者:行者123 更新时间:2023-12-04 22:46:33 25 4
gpt4 key购买 nike

我正在开发一种编程语言,September ,它使用标记的变体类型作为其主要值类型。 3 位用于类型(整数、字符串、对象、异常等),61 位用于实际值(实际整数、指向对象的指针等)。

很快,是时候添加 float输入语言。我几乎有 64 位 double 的空间,所以我想在内部使用 double 进行计算。由于我实际上是 3 位短存储,因此我必须在每次计算后将 double 舍入 - 基本上导致 61 位 double 数,尾数或指数短 3 位。

但!我知道浮点数充满危险,做一些对实数论文来说听起来很明智的事情可能会在 FP 数学中产生灾难性的结果,所以我向那里的专家提出一个开放式问题:

这种方法是否可行?通过在每一步四舍五入,我会在长时间运行的计算中遇到严重的错误累积问题吗?是否有一些特定的方法可以进行四舍五入以避免这种情况?是否有任何我无法以这种方式对待的特殊值(我想到了次常态)?

理想情况下,我希望我的浮点数像原生 61 位 double 数一样表现良好。

最佳答案

我建议从 double 格式的指数字段中借用位。这是this article中描述的方法(您将修改为从指数借用 3 位而不是 1)。使用这种方法,所有不使用非常大或非常小的中间结果的计算的行为与原始 double 计算完全相同。即使是运行到新格式的次正规区域的计算也表现 如果 1+8+52 61 位格式已被 IEEE 标准化,则完全相同 .

相比之下,天真地从有效数中借用任意数量的位会引入许多 double-rounding问题,您更频繁地从 52 位有效数四舍五入到仅删除几位的有效数。正如您在编辑问题时所建议的那样,从有效数中借用一位将是最糟糕的,一半的操作在统计上产生的双舍入结果与理想的“ native 61 位 double ”产生的结果不同。这意味着,基本运算不是精确到 0.5ULP,而是精确到 3/4ULP,精确度的巨大损失会使许多现有的、精心设计的数值算法脱轨,预计 0.5ULP。

不过,3 是从只有 11 的指数借用的大量位,您也可以考虑在您的语言中使用单精度 32 位格式(从主机调用单精度运算)。

最后,我在这里给出了 Jakub 找到的另一个解决方案的可见性:借用有效数的三位,并模拟 round-to-odd用于在转换为 49 显式有效位位、11 指数位格式的最接近数字之前的中间 double 计算。如果选择这种方式,请注意可以通过以下操作实现将自身舍入到有效数的 49 位:

if ((repr & 7) == 4) 
repr += (repr & 8) >> 1); /* midpoint case */
else
repr += 4;
repr &= ~(uint64_t)7; /* round to the nearest */

尽管处理与 double 具有相同表示的整数考虑到,即使数字从正常到次正常,从次正常到正常,或从正常到无限,上面的代码片段也能工作。您当然希望在如上释放的三个位中设置一个标记。要从未装箱的表示中恢复标准 double 数,只需使用 repr &= ~(uint64_t)7; 清除标记即可。 .

关于math - 以安全的方式将 64 位 IEEE 双倍截断为 61 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23112627/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com