【问题标题】:MIPS How can I calculate numbers greater than 1.111 x2^1023?MIPS 如何计算大于 1.111 x2^1023 的数字?
【发布时间】:2019-01-11 18:19:49
【问题描述】:

我正在使用 MIPS 和 MARS 4.5。 有什么方法可以计算扩展 1.111.. * 2^1023 范围的数字吗?

例如(阶乘函数):

.data
     dval:    .double   171.0  # its working up to 170!
     one:     .double   1.0  

.text
     l.d      $f2, dval
     l.d      $f4, one
     l.d      $f12, one
lo:  c.eq.d   $f2, $f4          # calc factorial of 171 = Infinity 
     bc1t     ex
     mul.d    $f12, $f12, $f2
     sub.d    $f2, $f2, $f4
     j        lo
ex:  li       $v0, 3
     syscall

如何计算和打印 171 的阶乘?

【问题讨论】:

  • 例如实现任意精度整数运算。
  • "有办法吗?"是的,您可以计算几乎高达“您的内存大小(以位为单位)”的数字 - 2 的幂(减去代码内存,您可能需要多个大精度值,因此备用内存除以任意精度数字的数量) , 甚至更多,如果你交换到磁盘。 “如何?” - 相当多的额外代码,因为本机整数类型最大为 32b,本机浮点类型最大为 64b(数字为 53b),因此较大的位数需要手动完成所有算术(位数在“我可以编码多少信息”)。
  • 正如下面在回答中指出的那样,您的代码确实仅使用大约 53 位来存储精确值,因此您已经在 171 处更快地丢失了数字(在右端)!您也只是用完了指数,但是缺少的底部部分可能已经使该值倾斜了很多。 (所以你的评论“工作到 170!”是“工作”,如“不会陷入/崩溃”,而不是“工作正常”)

标签: assembly floating-point double mips factorial


【解决方案1】:

在 FP 中计算阶乘令人惊讶。 FP 数的精度受尾数限制,实际上高于 ~20!,您需要超过 54 位来存储(整数)值,而 FP 结果只是一个近似值,因此不正确

但是,如果您只需要一个不精确的双精度值,我建议:

1/ 使用更简单的公式,例如斯特林公式。 https://en.wikipedia.org/wiki/Stirling%27s_approximation#Speed_of_convergence_and_error_estimates 如果在斯特林系列中保留 4 或 5 个数字,则由于使用此公式而导致的近似损失不会大于由于尾数有限而导致的损失。 (而且会更快)。

2/无论您使用阶乘还是斯特林,您都可以使用技巧来扩展双精度中的指数。这个想法只是为了保持指数低于 2^512 并且在每次 mult 之后,你做以下检查

 int extra_exponent=0;
 double theshold = 2^512;
 double threshold_inv=2^-512;
 ....
 # check exponent on n
 if (n>threshold) {
   n *= threshold_inv ; # reduce exponent
   extra_exponent++ ; # but keep track of it
 }

只要乘以

但最好的建议是使用无限精度算术。这是获得准确结果的唯一方法。

【讨论】:

    猜你喜欢
    • 2014-11-08
    • 2023-04-08
    • 2019-04-13
    • 2017-06-06
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    相关资源
    最近更新 更多