Assembly 双除法返回无穷大

Assembly 双除法返回无穷大,assembly,double,mips,division,mars-simulator,Assembly,Double,Mips,Division,Mars Simulator,我已将问题压缩为以下代码: .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, ret

我已将问题压缩为以下代码:

.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
而不是
无限

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

我对MIPS比较陌生,所以这可能很简单。
谢谢你的回答

第一次除法的明显成功归因于小正整数和正次正常双精度的表示方式。两者都有前导零,二进制位模式对应于最低有效位中值的有效位。将整数视为双精度整数的效果是将每个值除以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

第一次除法的明显成功归因于小正整数和正次正常双精度的表示方式。两者都有前导零,二进制位模式对应于最低有效位中值的有效位。将整数视为双精度整数的效果是将每个值除以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

第一次除法的明显成功归因于小正整数和正次正常双精度的表示方式。两者都有前导零,二进制位模式对应于最低有效位中值的有效位。将整数视为双精度整数的效果是将每个值除以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

第一次除法的明显成功归因于小正整数和正次正常双精度的表示方式。两者都有前导零,二进制位模式对应于最低有效位中值的有效位。将整数视为双精度整数的效果是将每个值除以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


看起来你在第二部分有一个打字错误:d区$f12,$f12,$f30。您从未显示要初始化的$f12,我怀疑它包含零。它不应该在'div.d$f12,$f2,$f30'之后包含某些内容吗?或者在调用打印时会被覆盖吗?
MTC1
指令不会将整数转换为双精度。搬家后您需要使用
CVT.D.W
。非常感谢!成功了!但是为什么第一个除法有效,第二个除法返回无穷大?我对MIPS ABI不太熟悉,但可能某些寄存器被
syscall
s破坏,不再包含您认为应该包含的值……看起来第二个除法中有一个输入错误:div.d$f12、$f12、$f30。您从未显示要初始化的$f12,我怀疑它包含零。它不应该在'div.d$f12,$f2,$f30'之后包含某些内容吗?或者在调用打印时会被覆盖吗?
MTC1
指令不会将整数转换为双精度。搬家后您需要使用
CVT.D.W
。非常感谢!成功了!但是为什么第一个除法有效,第二个除法返回无穷大?我对MIPS ABI不太熟悉,但可能某些寄存器被
syscall
s破坏,不再包含您认为应该包含的值……看起来第二个除法中有一个输入错误:div.d$f12、$f12、$f30。您从未显示要初始化的$f12,我怀疑它包含零。它不应该在'div.d$f12,$f2,$f30'之后包含某些内容吗?或者在调用打印时会被覆盖吗?
MTC1
指令不会将整数转换为双精度。搬家后您需要使用
CVT.D.W
。非常感谢!成功了!但是为什么第一个除法有效,第二个除法返回无穷大?我对MIPS ABI不太熟悉,但可能某些寄存器被
syscall
s破坏,不再包含您认为应该包含的值……看起来第二个除法中有一个输入错误:div.d$f12、$f12、$f30。您从未显示要初始化的$f12,我怀疑它包含零。它不应该在'div.d$f12,$f2,$f30'之后包含某些内容吗?或者在调用打印时会被覆盖吗?
MTC1
指令不会将整数转换为双精度。搬家后您需要使用
CVT.D.W
。非常感谢!成功了!但是为什么第一个除法有效,第二个除法返回无穷大呢?我对MIPS ABI不太熟悉,但可能某些寄存器被
系统调用
s所破坏,不再包含您认为应该包含的值……这是一个很好的答案!这是一个很好的例子,说明了多个bug是如何相互抵消的。谢谢,回答得很好。谢谢!回答得很好,这是一个g