x87 精度如何影响平方根?

2023-12-25

我编写了一些代码来测试 fsqrt 函数,但结果对我来说并不完全有意义。这是代码(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 的平方根。在 int_sqrt 中,其中一个精度行使 x87 使用 24 位精度作为 sqrt 精度,另一个使用 64 位精度。正如预期的那样,24 位版本的速度大大加快(10-20%,具体取决于输入)。

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

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

是这样的吗?


英特尔® 64 和 IA-32 架构软件开发人员手册,第 1 卷2A 第 3-291 页(FILD):

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

考虑数据存储在 FPU 内部always作为 80 位双扩展精度浮点数。 FILD和FISTdon't根据精度“忘记”位。精度的作用是在结果足够精确时中止计算,并取消相应的位然后.

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

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

So FSQRT在整个 80 位寄存器上工作并以 24 位精度中止。我怀疑它会在精度为 25 时中止以获得有效的舍入值。那么结果的“冗余”60位将被无效。您得到了一个 24 位结果,这对于 16 位整数来说已经足够了,正如您所注意到的那样。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

x87 精度如何影响平方根? 的相关文章

  • 在 x86 程序集中将整数打印到控制台

    当我在 16 位汇编中添加两个值时 将结果打印到控制台的最佳方法是什么 目前我有这个代码 CODE START mov ax 1 put 1 into ax add ax 2 add 2 to ax current value mov ah
  • 汇编-符号标志和奇偶校验标志

    我不明白什么时候设置标志标志 什么时候设置奇偶校验 据我所知 符号标志表示运算结果的符号 0表示正数 1表示负数 那么为什么在下一个代码中 mov al 5 sub al 124 SF为零 结果是负数 关于PF 为什么a和b中设置了PF a
  • 内联 asm 中不支持的指令“mov”将控制寄存器移动到 uint32_t

    我在 C 函数中使用汇编代码 但海湾合作委员会给出unsupported instruction mov 以下代码的错误 uint32 t faulting address asm volatile mov cr2 0 r faulting
  • CALL指令是否总是将EIP指向的地址压入堆栈?

    x86架构中函数调用时是否存在返回地址不入栈的情况 No CALL根据定义 将在跳转到目标地址之前将返回地址压入堆栈 该返回地址是EIP or RIP sizeof call instruction 通常为 5 个字节 英特尔 64 和 I
  • 奇怪的 MSC 8.0 错误:“ESP 的值未在函数调用中正确保存...”

    我们最近尝试将一些 Visual Studio 项目分解为库 并且在测试项目中一切似乎都编译和构建得很好 其中一个库项目作为依赖项 然而 尝试运行该应用程序给我们带来了以下令人讨厌的运行时错误消息 运行时检查失败 0 ESP 的值未在函数调
  • 为什么 Visual Studio 使用 xchg ax,ax

    我正在查看程序的反汇编 因为它崩溃了 并注意到很多 xchg ax ax 我用谷歌搜索了一下 发现它本质上是一个 nop 但是为什么 Visual Studio 会执行 xchg 而不是 noop 该应用程序是一个C NET3 5 64位应
  • 尝试使用 x86 程序集 GNU GAS 在数组索引处赋值时出现错误

    我在用x86GNU 与 GCC 的程序集 并尝试实现相当于以下内容的程序集c c int x 10 x 0 5 但是 当我尝试运行 使用命令 a out 我的汇编代码如下 第一次编译后gcc filename s 错误Segmentatio
  • 汇编8086监听键盘中断

    我有与此完全相同的问题 边画边听键盘 https stackoverflow com questions 13970325 8086 listen to keyboard while drawing 但第一个答案 接受的答案 只听键盘一次
  • 为什么 GCC 不将 a*a*a*a*a*a 优化为 (a*a*a)*(a*a*a)?

    我正在对科学应用程序进行一些数值优化 我注意到的一件事是 GCC 会优化调用pow a 2 通过将其编译成a a 但是调用pow a 6 没有优化 实际会调用库函数pow 这大大降低了性能 相比之下 英特尔 C 编译器 http en wi
  • 使用 Easy 68K (68000) 组装范围内的随机数

    我正在使用 Easy 68K 模拟器创建一个简单的黑杰克游戏 需要使用随机数来分配牌 我的牌必须在 2 到 11 的范围内 我似乎每次都得到相同的数字 但它不在我预期的范围内 我的卡值需要以 D3 结束 因此我有以下随机数代码 CLR L
  • 寄存器寻址模式与直接寻址模式

    我在试卷中遇到过这个问题 它指出 哪种给定的寻址模式更快 为什么 寄存器寻址方式 直接寻址方式 现在根据我的说法 寄存器寻址模式应该更快 因为寄存器是计算机中最快的存储位置 这是正确答案吗 请帮忙 谢谢 两种寻址模式之间的区别是 地址的来源
  • “rep stos”x86 汇编指令序列有什么作用?

    我最近偶然发现了以下汇编指令序列 rep stos dword ptr edi For ecx重复 存储内容eax到哪里edi指向 递增或递减edi 取决于方向标志 每次 4 个字节 通常 这用于memset型操作 通常 该指令简单地写成r
  • 如何知道寄存器是否是“通用寄存器”?

    我试图了解寄存器必须具备什么标准才能被称为 通用寄存器 我相信通用寄存器是一个可以用于任何用途的寄存器 用于计算 将数据移入 移出等 并且是一个没有特殊用途的寄存器 现在我读到了ESP寄存器是通用寄存器 我猜是ESP寄存器可以用于任何事情
  • 从 NASM 调用 C 函数 _printf 会导致分段错误

    我一直在尝试使用 NASM 在 Mac OS 和 Windows 上学习 64 位汇编 我的代码是 extern printf section data msg db Hello World 10 0 section text global
  • 大会,你好世界问题

    我正在 Linux 上学习 asm noobuntu 10 04 我得到了以下代码 http asm sourceforge net intro hello html http asm sourceforge net intro hello
  • ARMv8 A64 汇编中立即值的范围

    我的理解是 ARMv8 A64 汇编中的立即参数可以是 12 位长 如果是这样的话 为什么这行汇编代码是 AND X12 X10 0xFEF 产生此错误 使用 gcc 编译时 Error immediate out of range at
  • 程序集比较标志理解

    我正在努力理解汇编程序中的以下代码片段 if EAX gt 5 EBX 1 else EBX 2 在汇编程序中 可以写如下 根据我的书 模拟jge操作说明 https www felixcloutier com x86 jcc您通常会使用
  • 为什么如果内存组织为字,则程序计数器加 1;如果内存组织为字节,则程序计数器加 2?

    如果在计算机中一条指令是 16 位 并且如果存储器被组织为 16 位字 则通过在当前指令的地址中加 1 来计算下一条指令的地址 如果内存是按字节组织的 可以单独寻址 那么我们需要在当前指令地址上加二 得到顺序执行的下一条指令的地址 为什么会
  • 这个反斜杠在这段汇编代码中起什么作用?

    我不确定这些推线有什么区别 修剪下来来自 Linux 的 x86 entry calling h https github com torvalds linux blob 241e39004581475b2802cd63c111fec43b
  • FreePascal x64 上系统单元函数的汇编调用

    我有一些 Delphi 汇编代码 可以在 Win32 Win64 和 OSX 32 上编译并正常工作 XE2 但是 由于我需要它在 Linux 上工作 所以我一直在考虑编译它的 FPC 版本 到目前为止 Win32 64 Linux32 6

随机推荐

  • 如何在 IntelliJ 中运行同一个应用程序两次?

    我正在使用 IntelliJ 开发我的客户端 服务器应用程序 并且刚刚发现了Compounds 基本上我可以同时运行我的客户端和服务器 并且每次我想测试时它都可以节省我无用的操作 但是 我想用 2 个客户端和 1 个服务器来测试我的应用程序
  • Java 2D:将点 P 移动到靠近另一个点一定距离?

    将 Point2D Double x 距离移近另一个 Point2D Double 的最佳方法是什么 编辑 尝试编辑 但因维护而停机 不 这不是作业 我需要将飞机 A 移向跑道末端 C 并将其指向正确的方向 角度 a 替代文本http im
  • 兑换 + 点击一次 = :-(

    我有一个普通的 Windows 窗体程序 不是 VSTO 它使用单击一次进行部署 问题是 很多用户都遇到随机错误的问题 通常会指出 由于以下错误 IClassFactory 失败 80004005 我通过将模式更改为 隔离 来部署救赎 这似
  • 以百分比形式给出省略号

    我正在尝试省略span里面的元素td元素 问题是省略号有效当且仅当我给出span元素具有固定宽度 即宽度 以像素为单位 但在我的项目中 我不能使用固定宽度span元素 这span元素必须完全拉伸到各自的内部td可以通过使用的元素width
  • Unix - 在 shell 脚本中排序

    如何根据字段位置对文件进行排序 例如 我需要对下面给定的文件进行排序 基于第 4 5 和 8 名位置 请帮忙 我尝试了以下命令 它不起作用 sort d k 3 42 44 k 4 47 57 k 5 59 70 k 8 73 82 010
  • 如何从外部功能镜头转向功能镜头

    在我开始更好地使用函数式编程的过程中 在 SO 家族成员的帮助下 我发现了什么lens https bartoszmilewski com category lens 我什至通过下面的链接对其进行了一些研究 以了解有关它们的更多信息 htt
  • 如何与剧作家一起下载?

    我正在尝试使用以下命令从网站下载文件剧作家 https github com microsoft playwright 触发下载的按钮做了一些js 然后开始下载 使用单击按钮 click函数触发下载但显示错误 失败 下载错误 我尝试过使用
  • 我可以在 Mono CSharpRepl 中重新加载程序集吗?

    因此 我有 Python 背景 现在开始在 Mac 上使用 C 和 Mono 我最近才发现Mono CSharpRepl 工具 http www mono project com CsharpRepl并希望使用它来实现与 Python 中类
  • Java中的互斥方法执行

    我有两种方法 a and b 虽然我可以接受多个线程同时访问任何方法 这是可取的 但我不希望任何线程进入a while b 正在被执行 我怎么做 Edit 1 假设有 4 个线程Thread 1正在访问A 我想要的是所有 4 个线程都不应该
  • Angular REST API 安全性

    当我使用 Angular 消费 REST API 请求时 我的应用程序出现问题 Web 服务 URL 存储在 Angular 服务或控制器 js 文件中 因此 如果我有登录网络服务来检查用户名和密码 例如 最终用户或开发人员可以获取此网址并
  • 测试未通过:未定义方法“验证!”对于 nil:NilClass?

    我有以下失败 Failures 1 RelationshipsController creating a relationship with Ajax should increment the Relationship count Fail
  • 页面重新加载后记住 jQuery 选项卡位置

    我有一个包含一些 GridView 的页面 我使用选项卡菜单将它们保存在选项卡中 有四个选项卡 我的问题是 当页面重新加载时 选项卡会重置为第一个选项卡 HTML div class tabbed box nbsp nbsp div cla
  • 嵌入 hsql 的一些有趣的事情

    我只是对某些事情感到好奇 我在我的项目中使用 hsql 当然是嵌入式的 有时我觉得需要可视化 hibernate 生成的内容 我拿了一份 dbvisualizer 的免费副本 这是 hsqljdbc properties jdbc url
  • 如何为 postgres 编写 DELETE CASCADE?

    我正在为 postgres 手动构建 DELETE CASCADE 语句 我有一个 交易 和一个 切片 表 相关关系如下所示 Table public slice Column Type Modifiers id text not null
  • 如何在 Hadoop mapReduce 中获取 Kerberos 而不是委托令牌?

    我是一名 Java 用户 当向 Hadoop mapReduce 提交作业时 它使用 Kerberos 对 Hadoop 进行身份验证 成功后会创建委派令牌 并将其与作业提交一起传递给 Hadoop 而不是 kerberos 票证 出于安全
  • 当 SQL 查询受限时与调用整行相比,性能有何优势?

    通过在查询中仅选择所需字段而不是查询整行 可以带来多少性能优势 例如 如果我有一行 10 个字段 但只需要显示 5 个字段 是否值得只查询这 5 个字段 此限制带来的性能优势与稍后需要返回并在 sql 查询中添加字段的风险相比有何不同 您需
  • 如何在 Objective C 中将类对象转换为 json 字符串

    1 我创建类对象 然后使用此代码为我的类添加值 csJastorPollQuestion pq csJastorPollQuestion alloc initWithID 01 Name AAA 2 我在 NSLog 中显示了 csJast
  • Flask Restful NoAuthorizationError 缺少授权标头

    我使用 Python 3 6 在生产模式下在服务器上运行 Flask Restful 并访问需要 jwt 身份验证的端点 但我不断收到 NoAuthorizationError Missing Authorization Header 错误
  • InputText PrimeFaces 不应用 maxlength

    我将 PrimeFaces 3 4 与 PrimeFaces Mobile 0 9 3 结合使用 我在 inputText 属性中指定了 maxlength 但它没有在 HTML 中呈现 我的代码
  • x87 精度如何影响平方根?

    我编写了一些代码来测试 fsqrt 函数 但结果对我来说并不完全有意义 这是代码 delphi 中 uses mmsystem var rand longint 123456789 function rng longint asm imul