我正在尝试将所有浮点数写入.001精度到-∞。我已将RC字段设置为01二进制,但我只能打印出所需精度的初始浮点数,然后忽略舍入。我想我可能会错过一些关于如何处理-∞精度的明显内容,但我不确定。
INCLUDE Irvine32.inc
.data
ctrlWord WORD 010000000000b ; set the RC field to round down toward -∞.
.code
fild sum ; load integer into ST(0)
fidiv count ; divide ST(0) by mem int
fstcw ctrlWord ; store control word
fldcw ctrlWord ; load control word
call WriteFloat ; +2.5000000E+000
fild stdDev ; load variance integer into ST(0)
fidiv count ; average the result
fsqrt ; ST(0) = square root
call WriteFloat ; +2.5495097E+000
答案 0 :(得分:1)
FPU的舍入模式仅适用于浮点尾数的最后二进制数字。它不能用于十进制舍入。该舍入规则有一个例外:FRNDINT
。该指令“将ST(0)寄存器中的源值舍入为最接近的整数值,具体取决于当前的舍入模式(FPU控制字的RC字段的设置),并将结果存储在ST(0)中。” (Intel Manual)。
对于十进制舍入,您可以使用FRNDINT
使用技巧:首先计算n * 10 ^ x(x是小数部分的所需小数精度)。然后使用FRNDINT
对整数部分进行舍入并截断小数部分。最后,您可以将数字除以10 ^ x,或者您可以将数字转换为字符串并插入适当的小数点。
看看这个例子(这是你的代码,只是稍作修改):
INCLUDE Irvine32.inc
.data
newCtrlWord WORD 010000000000b ; set the RC field to round down toward -∞.
oldCtrlWord WORD ?
sum WORD 25
count WORD 10
stdDev WORD 65
thousand WORD 1000
.code
main:
fstcw oldCtrlWord ; store control word
mov ax, oldCtrlWord
and ah, 11110011b ; clear _only_ RC field
or ah, 00000100b ; set _only_ RC field (rounding to -∞)
mov newCtrlWord, ax
fldcw newCtrlWord ; load control word
fild sum ; load integer into ST(0)
fidiv count ; divide ST(0) by mem int
fimul thousand ; thousand=10^3 - preserve three decimal digits of the fractional part
frndint ; only for this you need the control word
fidiv thousand ; adjust integer to a correct rational number (reverse the `fimul thousand`)
call WriteFloat ; +2.5000000E+000
call CRLF
fild stdDev ; load variance integer into ST(0)
fidiv count ; average the result
fsqrt ; +2.5495097E+000
fimul thousand ; thousand=10^3 - preserve three decimal digits of the fractional part
frndint ; only for this you need the control word
fidiv thousand ; adjust integer to a correct rational number (reverse the `fimul thousand`)
call WriteFloat ; +2.5490000E+000
call CRLF
fldcw oldCtrlWord ; restore control word
exit
END main