浮動小数点演算を使用せずにMIPSアセンブリで2つのIEEE 754数値を掛けようとしています。MIPSで2つのIEEE 754浮動小数点数を掛ける
私は私が考える仮数セクションとのトラブルを抱えています2つの浮動小数点の$ A0に保存されている数字と$ A1
multiply_fp: #$s0 = final sign bit, $s1 = final exponent, $s2 = final mantissa
#check the sign bit
srl $t1, $a0, 31 # leave just sign bit
srl $t2, $a1, 31 # leave just sign bit
bnez $t1, negative # check if sign bit is 1
bnez $t2, negative # check if sign bit is 1
positive:
addi $s0, $zero, 0 # set sign bit to 0
j exponent
negative:
addi $s0, $zero, 10000000000000000000000000000000 #set sign bit to 1
exponent:
andi $t1, $a0, 01111111100000000000000000000000 #get exponent bits from fp1
andi $t2, $a1, 01111111100000000000000000000000 #get exponent bits from fp2
srl $t1, $t1, 23 #move them all the way to the right
srl $t2, $t2, 23
add $s1, $t1, $t2 #add them together
addi $s1, $s1, -127 #subtract 127 from the sum
sll $s1, $s1, 23 #move them back to the right position
mantissa:
andi $t1, $a0, 00000000011111111111111111111111 #get the mantissa bits from fp1
andi $t2, $a1, 00000000011111111111111111111111 #get the mantissa bits from fp2
ori $t1, $t1, 00000000100000000000000000000000 #add a 1 at the msb
ori $t2, $t2, 00000000100000000000000000000000
mul $s2, $t1, $t2 #multiply the mantissas
andi $s2, 00000000011111111111111111111111 #cut the 1 back off
combine:
or $v0, $s0, $s1
or $v0, $v0, $s2
jr $ra
を持っています。私の論理によれば、小数部分を掛けて1を取り除くことになります。例えば1.011 * 1.010 = 1.10111とすると、先頭の1を切り捨てて10111を新しい仮数にします。小数点を削除するだけで1011 * 1010 = 110111となり、先頭の1を切り捨てて10111になります。
しかし、mul関数は非常に奇妙な結果を出しています。理由はわかりません。誰も私の論理でエラーを見ることができますか?
_ "非常に奇妙な結果" _は良い問題の説明ではありません。インプットとアウトプット(予想と実際)は何でしたか?問題が 'mul'であると主張しているので、その命令の値を表示してください。PS:仮数が24ビットであることは分かりますので、64ビットの乗算が必要ですか? – Jester
ヒント:製品の符号は2つのオペランドの符号のXORです – Nayuki
一般に、正規化、オーバーフロー、アンダーフロー、サブノーマル、無限大、NaNに対処する必要があるため、ビットレベルの浮動小数点操作は非常に困難です。私は完全に機能する乗算ルーチンがあなたが示したように3倍のコードを取ることを期待しています – Nayuki