0

我将我的问题浓缩为以下代码:

.data

newline: .asciiz "\n"

.text
.globl main

main:

li $t0, 4
li $t1, 16          

mtc1 $t0, $f2       # Two integers get stored as floats
mtc1 $t1, $f30

div.d $f12, $f2, $f30

li $v0, 3
syscall         # First division works, returns 0.25

la $a0, newline
li $v0, 4
syscall         # prints new line

div.d $f12, $f12, $f30

li $v0, 3
syscall         # Second division doesn't work as expected, returns Infinity

输出是:

0.25

Infinity

这是为什么?我希望0.25/16是 ~0.015625而不是Infinity.

$f12 的第一个值:0x3fd0000000000000 $f12 的第二个值:0x7ff0000000000000

我对 MIPS 比较陌生,所以它可能很容易。感谢您的任何回答!

4

1 回答 1

3

第一次除法的明显成功是由于小正整数和正次正规双精度如何表示的人工制品。两者都有前导零,二进制位模式对应于最低有效位中值的有效位。将整数视为双精度数的效果是将每个值除以 2 的 1074 次幂。

虽然 f2 和 f30 被视为双精度浮点数,但包含的值很小,大约为 2.0E-323 和 7.9E-323,但它们的比率与 4/16 相同。将中等数字(例如 0.25)除以很小的数字会溢出到无穷大。

这是一个简短的 Java 程序来说明这一点:

public class Test {
  public static void main(String[] args) {
    long t0 = 4;
    long t1 = 16;
    double f2 = Double.longBitsToDouble(t0);
    double f30 = Double.longBitsToDouble(t1);
    System.out.println("f2=" + f2);
    System.out.println("f30=" + f30);
    double f12 = f2 / f30;
    System.out.println("f12=" + f12);
    System.out.println("f12/f30=" + f12 / f30);
  }
}

输出:

f2=2.0E-323
f30=7.9E-323
f12=0.25
f12/f30=Infinity
于 2014-06-12T19:49:10.470 回答