Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 检查精度的FPU指令_Delphi_X86_Fpu_X87 - Fatal编程技术网

Delphi 检查精度的FPU指令

Delphi 检查精度的FPU指令,delphi,x86,fpu,x87,Delphi,X86,Fpu,X87,使用fldcw指令,可以将FPU单元的精度更改为24位或更多位。然而,在做了一些测试之后,我开始认为实际上很少有x87操作使用这种设置 我还没有测试所有的操作,但是到目前为止,在这个测试机器上,看起来只有fdiv和fsqrt在选定的精度下停止计算,并且所有其他操作(fadd fsub fmul…)总是计算完全扩展精度 如果是这样的话,我希望是这样的,因为这两条指令(fdiv和fsqrt)比大多数其他x87 FPU指令要慢得多,所以当精度足够低时,可以加快速度,但实际上,我只是想知道这是否一直都是

使用fldcw指令,可以将FPU单元的精度更改为24位或更多位。然而,在做了一些测试之后,我开始认为实际上很少有x87操作使用这种设置

我还没有测试所有的操作,但是到目前为止,在这个测试机器上,看起来只有fdiv和fsqrt在选定的精度下停止计算,并且所有其他操作(fadd fsub fmul…)总是计算完全扩展精度

如果是这样的话,我希望是这样的,因为这两条指令(fdiv和fsqrt)比大多数其他x87 FPU指令要慢得多,所以当精度足够低时,可以加快速度,但实际上,我只是想知道这是否一直都是这样,或者这是我的测试机器中使用的最新处理器的一个怪癖

编辑:下面是显示它的delphi代码

program Project1;

uses
  windows,dialogs,sysutils;

{$R *.res}

const
 test_mul:single=1234567890.0987654321;

var
 i:longint;
 s:single absolute i;
 s1,s2,s3:single;

procedure test_24;
asm
 mov word([esp-2]),$103f  // 24bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s1]
end;

procedure test_53;
asm
 mov word([esp-2]),$123f  // 53bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s2]
end;

procedure test_64;
asm
 mov word([esp-2]),$133f  // 64bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s3]
end;

begin
 i:=0;
 repeat
  test_24;
  test_53;
  test_64;

  if (s1<>s2) or (s2<>s3) then begin
   showmessage('Error at step:'+inttostr(i));
   break;
  end;

  inc(i);
 until i=0;
 showmessage('No difference found between precisions');
end.
程序项目1;
使用
窗口、对话框、系统工具;
{$R*.res}
常数
测试单元:单个=1234567890.0987654321;
变量
i:长型;
s:单绝对i;
s1、s2、s3:单一;
程序测试24;
asm
mov字([esp-2]),103f美元//24位精度,trunc
fldcw字([esp-2])
佛罗里达州[南]
fmul[测试工具]
fstp[s1]
结束;
程序测试53;
asm
mov字([esp-2]),$123f//53位精度,trunc
fldcw字([esp-2])
佛罗里达州[南]
fmul[测试工具]
fstp[s2]
结束;
程序测试64;
asm
mov字([esp-2]),133f//64位精度,trunc
fldcw字([esp-2])
佛罗里达州[南]
fmul[测试工具]
fstp[s3]
结束;
开始
i:=0;
重复
测试24;
测试单元53;
测试64;
如果(s1s2)或(s2s3),则开始
showmessage('步骤出错'+inttostr(i));
打破
结束;
公司(一);
直到i=0;
showmessage(“精度之间未发现差异”);
结束。
edit2:假警报,我错了,我存储为单存储而不是扩展存储,因此无法捕捉差异,这里有一个固定测试,感谢hans passant捕捉到我的错误:

program Project1;

uses
  windows,dialogs,sysutils;

{$R *.res}

const
 test_mul:single=1234567890.0987654321;

var
 i:longint;
 errors:cardinal;
 s:single absolute i;
 s1,s2,s3:extended;

procedure test_24;
asm
 mov word([esp-2]),$103f  // 24bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s1]
end;

procedure test_53;
asm
 mov word([esp-2]),$123f  // 53bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s2]
end;

procedure test_64;
asm
 mov word([esp-2]),$133f  // 64bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s3]
end;

begin
 errors:=0;
 i:=0;
 repeat
  test_24;
  test_53;
  test_64;

  if (s1<>s2) or (s2<>s3) then begin
   inc(errors);
  end;

  inc(i);
 until i=0;
 showmessage('Number of differences between precisions: '+inttostr(errors));
end.
程序项目1;
使用
窗口、对话框、系统工具;
{$R*.res}
常数
测试单元:单个=1234567890.0987654321;
变量
i:长型;
错误:基数;
s:单绝对i;
s1,s2,s3:扩展;
程序测试24;
asm
mov字([esp-2]),103f美元//24位精度,trunc
fldcw字([esp-2])
佛罗里达州[南]
fmul[测试工具]
fstp[s1]
结束;
程序测试53;
asm
mov字([esp-2]),$123f//53位精度,trunc
fldcw字([esp-2])
佛罗里达州[南]
fmul[测试工具]
fstp[s2]
结束;
程序测试64;
asm
mov字([esp-2]),133f//64位精度,trunc
fldcw字([esp-2])
佛罗里达州[南]
fmul[测试工具]
fstp[s3]
结束;
开始
误差:=0;
i:=0;
重复
测试24;
测试单元53;
测试64;
如果(s1s2)或(s2s3),则开始
inc(错误);
结束;
公司(一);
直到i=0;
showmessage('精度之间的差异数:'+inttostr(错误));
结束。

您能告诉我们复制此(汇编代码,…)的方法吗?请注意,有些库可能会“有帮助地”为您重置浮点控制字。哦,我刚刚编写了直接汇编程序代码,没有令人惊讶的代码。我将在5-10分钟内编辑一些代码,我将完成另一个问题的输入。当然,在现代处理器上,你不能使一条指令只占用一个周期的速度更快。@HansPassant存在双舍入的问题,这会使计算达到全精度适得其反,即使处理器在一个周期内有足够的时间进行计算,甚至更多。不确定代码试图证明什么,但是如果您想看到差异,那么必须将结果存储在双精度变量中。