首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >x87精度如何影响平方根?

x87精度如何影响平方根?
EN

Stack Overflow用户
提问于 2014-05-31 00:31:24
回答 1查看 417关注 0票数 3

我编写了一些代码来测试fsqrt函数,结果对我来说并不完全合理。下面是代码(在delphi中):

代码语言:javascript
复制
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%取决于输入)。

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

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

这就是发生的事吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-31 17:04:32

Intel 64和IA-32架构软件开发人员手册,第2A卷,第3至291页(文件):

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

假设数据存储在FPU 中,始终以80位双扩展精度浮点数的形式存储。FILD和FIST 不根据精度“忘记”位。精度的影响是,当计算结果足够精确时,中止计算,并在后取消适当的位数

Intel 64和IA-32架构软件开发人员手册第1卷第8.1.5.2章(精确控制字段):

使用这些设置将取消双扩展精度浮点格式的64位意义和长度的优点。当指定降低精度时,意义和值的舍入将清除未使用的位,并将其转换为零。

因此,FSQRT工作在完整的80位寄存器上,并以24位的精度中止.我怀疑它以25的精度中止,以获得舍入的重要值。然后,结果的“冗余”60位将被取消。您已经得到了一个24位的结果,这足够一个16位整数,正如您注意到的正确。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23965243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档