x87 精度如何影响平方根? [英] how x87 precision affects square roots?

查看:23
本文介绍了x87 精度如何影响平方根?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一些代码来测试 fsqrt 函数,结果对我来说并不完全有意义.这是代码(在delphi中):

I wrote some code to test the fsqrt function and the result doesn't make complete sense to me. Here's the code (in delphi):

uses
 mmsystem;

var
 rand:longint=123456789;

function rng:longint;
asm
 imul eax,[rand],$08088405
 inc eax
 mov [rand],eax
end;

function int_sqrt(adata:longint):longint;
asm
 fnstcw word([esp-2])

// mov word([esp-4]),$1f3f  // 80bit precision
 mov word([esp-4]),$1c3f  // 24bit precision
 fldcw word([esp-4])

 mov [esp-8],eax
 fild longint([esp-8])

 fsqrt

 fistp longint([esp-8])
 mov eax,[esp-8]

 fldcw word([esp-2])
end;

procedure TForm1.FormCreate(Sender: TObject);
var
 start,i,r,s1,s2:longint;
 time0,time1:longint;
begin
 timebeginperiod(1);
 time0:=timegettime;

 start:=1000000000;
 for i:=(start+0) to (start+100000000) do begin
  //r:=i;
  r:=abs(rng);
//  r:=2134567890;
//  r:=$7fffffff;
  s1:=int_sqrt(r);
  s2:=trunc(sqrt(r));
  if s1<>s2 then
   showmessage('error: '+inttostr(r)+'/'+inttostr(s1)+'/'+inttostr(s2));
 end;

 time1:=timegettime;
 timeendperiod(1);
 showmessage('Milliseconds: '+inttostr(time1-time0));
end;

很简单,我正在寻找一个整数的平方根.在 int_sqrt 中,精度行之一让 x87 使用 24 位精度作为 sqrt 精度,另一个 64 位精度.正如预期的那样,24 位版本的速度要快很多(10-20% 取决于输入).

Simple enough, I'm looking for the square root of an int. In the int_sqrt one of the precision lines gets the x87 to use 24 bit precision for the sqrt precision, the other 64 bit precision. As expected, the 24 bit version is faster by a good margin (10-20% depending on input).

问题来了.我还没有找到在使用 24 位精度时返回错误结果的单个 32 位(实际上是 31 位,最后一位是未使用的符号)int!

Here's the problem though. I haven't found a single 32bit (well 31bit actually, the last bit is unused sign) int that returns a wrong result when using 24bit precision!!

到目前为止我唯一的理论是只有最终结果取决于精度,而不是源或任何中间缓冲区.这是有道理的,因为 31 位整数的平方根的最大结果大小是 16 位.

My only theory so far is that only the final result depends on the precision, not the source or any intermediate buffer. That would make sense since the maximum result size for the square root of a 31bit int is 16bit.

这是怎么回事?

推荐答案

Intel® 64 and IA-32 Architectures Software Developer's Manual Vol.2A 第 3-291 页(FILD):

Intel® 64 and IA-32 Architectures Software Developer’s Manual Vol. 2A Page 3-291 (FILD):

将有符号整数源操作数转换为双精度扩展精度浮点格式并将值推送到FPU 寄存器堆栈.源操作数可以是一个字、双字或四字整数.加载时没有舍入错误.

Converts the signed-integer source operand into double extended-precision floating-point format and pushes the value onto the FPU register stack. The source operand can be a word, doubleword, or quadword integer. It is loaded without rounding errors.

考虑将数据存储在 FPU 中总是作为 80 位双扩展精度浮点数.FILD 和 FIST 不要根据精度忘记"位.精度的作用是在结果足够精确时中止计算,并在之后取消适当的位.

Consider that data are stored inside the FPU always as 80-bit double extended-precision floating-point numbers. FILD and FIST don't "forget" bits according to the precision. The effect of precision is to abort a calculation when the result is enough precise, and to nullify the appropriate bits afterwards.

英特尔® 64 位和 IA-32 架构软件开发人员手册卷.1 第 8.1.5.2 章(精准控制领域):

Intel® 64 and IA-32 Architectures Software Developer’s Manual Vol. 1 Chapter 8.1.5.2 (Precision Control Field):

使用这些设置会抵消双倍的优势扩展精度浮点格式的 64 位有效位长度.当指定降低精度时,有效数的舍入value 将右侧未使用的位清零.

Using these settings nullifies the advantages of the double extended-precision floating-point format's 64-bit significand length. When reduced precision is specified, the rounding of the significand value clears the unused bits on the right to zeros.

所以 FSQRT 在完整的 80 位寄存器上工作并以 24 位的精度中止.我怀疑它以 25 的精度中止以获得四舍五入的重要值.然后结果的冗余"60 位将被取消.您有一个 24 位的结果,这对于您认为正确的 16 位整数来说已经足够了.

So FSQRT works on the full 80-bit-register and aborts at a precision of 24 bits. I suspect that it aborts at a precision of 25 to get a significant value for rounding. Then the "redundant" 60 bits of the result will be nullified. You've got a 24-bit result and that is enough for a 16-bit integer as you noticed correct.

这篇关于x87 精度如何影响平方根?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆