整数 sqrt 的精度

2024-02-24

我有一个这样的循环:

for(uint64_t i=0; i*i<n; i++) {

这需要每次迭代都进行乘法。如果我可以在循环之前计算 sqrt 那么我可以避免这种情况。

unsigned cut = sqrt(n)
for(uint64_t i=0; i<cut; i++) {

就我而言,如果 sqrt 函数向上舍入到下一个整数是可以的,但如果向下舍入则不行。

我的问题是: sqrt 函数是否足够准确,可以在所有情况下执行此操作?

编辑:让我列出一些案例。如果 n 是完全平方数,那么n = y^2我的问题是 - 是cut=sqrt(n)>=y对于所有 n?如果 cut=y-1 那么就有问题了。例如。如果 n = 120 并且 cut = 10 没问题,但是如果 n=121 (11^2) 并且 cut 仍然是 10 那么它就不起作用。

我首先担心的是 float 的小数部分只有 23 位和 double 52,因此它们无法存储某些 32 位或 64 位整数的所有数字。不过,我认为这不是问题。假设我们想要某个数字 y 的 sqrt,但我们无法存储 y 的所有数字。如果我们让可以存储的 y 分数为 x,我们可以写成 y = x + dx,那么我们要确保我们选择的任何 dx 都不会移动到下一个整数。

sqrt(x+dx) < sqrt(x) + 1  //solve
dx < 2*sqrt(x) + 1 
// e.g for x = 100 dx < 21
// sqrt(100+20) < sqrt(100) + 1

浮点数可以存储 23 位,因此我们让 y = 2^23 + 2^9。这已经足够了,因为 2^9

unsigned xi = -1-1;
printf("%u %u\n", xi, (unsigned)(float)xi);  //4294967294 4294967295
printf("%u %u\n", (unsigned)sqrt(xi), (unsigned)sqrtf(xi));  //65535 65536

由于 float 无法存储 2^31-2 的所有数字,因此 double 可以得到不同的 sqrt 结果。但 sqrt 的浮点版本要大一个整数。这就是我要的。对于 64 位整数,只要 double 的 sqrt 始终向上舍入就可以了。


首先,整数乘法确实非常便宜。只要每个循环迭代有多个工作周期和一个备用执行槽,它就应该通过在大多数非小型处理器上重新排序而完全隐藏。

如果您确实有一个整数乘法速度非常慢的处理器,那么一个真正聪明的编译器可能会将您的循环转换为:

for (uint64_t i = 0, j = 0; j < cut; j += 2*i+1, i++)

将乘法替换为lea或一个班次和两个加法。


撇开这些注释不谈,让我们看看你所说的问题。不,你不能只使用i < sqrt(n)。反例:n = 0x20000000000000。假设遵守 IEEE-754,您将拥有cut = 0x5a82799, and cut*cut is 0x1ffffff8eff971.

然而,基本的浮点误差分析表明计算中的误差sqrt(n)(转换为整数之前)以 ULP 的 3/4 为界。所以您可以安全地使用:

uint32_t cut = sqrt(n) + 1;

并且您最多将执行一次额外的循环迭代,这可能是可以接受的。如果您想完全精确,请改用:

uint32_t cut = sqrt(n);
cut += (uint64_t)cut*cut < n;

Edit: z boson澄清说,就他的目的而言,这仅在以下情况下才重要:n是一个精确的平方(否则,得到的值为cut“太小了”是可以接受的)。在这种情况下,不需要进行调整,可以安全地使用:

uint32_t cut = sqrt(n);

为什么这是真的?实际上,这很简单。转换n to double引入扰动:

double_n = n*(1 + e)

这满足|e| < 2^-53。该值的数学平方根可以展开如下:

square_root(double_n) = square_root(n)*square_root(1+e)

现在,自从n假设是最多 64 位的完美平方,square_root(n)是一个最多 32 位的精确整数,并且是我们希望计算的数学精确值。来分析square_root(1+e)术语,使用泰勒级数1:

square_root(1+e) = 1 + e/2 + O(e^2)
                 = 1 + d with |d| <~ 2^-54

因此,数学上的精确值square_root(double_n)与[1]所需的精确答案的距离不到 ULP 的一半,并且必须舍入到该值。

[1] 我在这里滥用相对误差估计,其中 ULP 的相对大小实际上在二进制文件中有所不同 - 我试图在不陷入太多困境的情况下提供一点证明的味道往下看细节。这一切都可以做得非常严格,只是对于 Stack Overflow 来说有点啰嗦。

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

整数 sqrt 的精度 的相关文章

  • Tensorflow 中的自定义资源

    由于某些原因 我需要为 Tensorflow 实现自定义资源 我试图从查找表实现中获得灵感 如果我理解得好的话 我需要实现3个TF操作 创建我的资源 资源的初始化 例如 在查找表的情况下填充哈希表 执行查找 查找 查询步骤 为了促进实施 我
  • C++ 中的软(不是:弱)引用 - 这可能吗?有实施吗?

    在 C 中我正在使用boost shared ptr and boost weak ptr自动删除不再需要的对象 我知道这些与引用计数一起工作 在 Java 中 内存由垃圾收集器管理 它将内置对象引用视为strong WeakReferen
  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 使用实体框架从集合中删除项目

    我正在使用DDD 我有一个 Product 类 它是一个聚合根 public class Product IAggregateRoot public virtual ICollection
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • 如何在 VS 中键入时显示方法的完整文档?

    标题非常具有描述性 是否有任何扩展可以让我看到我正在输入的方法的完整文档 我想查看文档 因为我可以在对象浏览器中看到它 其中包含参数的描述和所有内容 而不仅仅是一些 摘要 当然可以选择查看所有覆盖 它可能是智能感知的一部分 或者我不知道它并
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • 为什么 FTPWebRequest 或 WebRequest 通常不接受 /../ 路径?

    我正在尝试从 ftp Web 服务器自动执行一些上传 下载任务 当我通过客户端甚至通过 Firefox 连接到服务器时 为了访问我的目录 我必须指定如下路径 ftp ftpserver com AB00000 incoming files
  • 范围和临时初始化列表

    我试图将我认为是纯右值的内容传递到范围适配器闭包对象中 除非我将名称绑定到初始值设定项列表并使其成为左值 否则它不会编译 这里发生了什么 include
  • 如何排列表格中的项目 - MVC3 视图 (Index.cshtml)

    我想使用 ASP NET MVC3 显示特定类型食品样本中存在的不同类型维生素的含量 如何在我的视图 Index cshtml 中显示它 an example 这些是我的代码 table tr th th foreach var m in
  • 从匿名类型获取值

    我有一个方法如下 public void MyMethod object obj implement 我这样称呼它 MyMethod new myparam waoww 那么我该如何实施MyMethod 获取 myparam 值 Edit
  • C# 搜索目录中包含字符串的所有文件,然后返回该字符串

    使用用户在文本框中输入的内容 我想搜索目录中的哪个文件包含该文本 然后我想解析出信息 但我似乎找不到该字符串或至少返回信息 任何帮助将不胜感激 我当前的代码 private void btnSearchSerial Click object
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 如何检测 C# 中该字典键是否存在?

    我正在使用 Exchange Web 服务托管 API 和联系人数据 我有以下代码 即功能性的 但并不理想 foreach Contact c in contactList string openItemUrl https service
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • 为什么 Ajax.BeginForm 在 Chrome 中不起作用?

    我正在使用 c NET MVC2 并尝试创建一个 ajax 表单来调用删除数据库记录 RemoveRelation 的方法 删除记录的过程正在按预期进行 删除记录后 表单应调用一个 JavaScript 函数 从视觉效果中删除该记录 Rem
  • Swagger 为 ASP.CORE 3 中的字典生成错误的 URL

    当从查询字符串中提取的模型将字典作为其属性之一时 Swagger 会生成不正确的 URL 如何告诉 Swagger 更改 URL 中字典的格式或手动定义输入参数模式而不自动生成 尝试使用 Swashbuckle 和 NSwag 控制器 pu
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12

随机推荐

  • 查找数组的最大切片 | JavaScript

    我需要找到包含不超过两个不同数字的数组的最大切片 这是我的数组 1 1 1 2 2 2 1 1 2 2 6 2 1 8 我对此的思考过程是找到不重复的数字并在新数组中返回它们的索引 这是我到目前为止所拥有的 function goThrou
  • 在 Python 的 sqlite3 中使用外键

    我正在编写一个通过 python 创建 sqlite3 数据库的程序 我有一个作者表 AuthorID Name 和第二个图书表 BookID Title AuthorID 我创建的这些表如下所示 Authors sqlite3 conne
  • Twitter Bootstrap 3.0 行比窗口宽

    我正在摆弄 Twitter Bootstrap 并注意到我的 row比屏幕长度更宽 这里是example http bootply com 90307 当 bootstrap 3 0 出来时我没有经历过这个 右侧的额外空间来自margin
  • 如何检测WKWebView中的hash变化?

    我有一个使用 javascript 的网站 它使用 Angular 来控制您在网站上看到的内容 所以http somewebsite com page1 http somewebsite com page1显示 当您单击位置更改为的选项卡时
  • 用于计算矩阵指数的 C++ 库

    对于实现矩阵指数计算的库有什么建议吗 Expokit http www maths uq edu au expokit 用 Fortran 编写 但可以嵌入 C 中 它工作得很好 并且包含稀疏矩阵的优化算法
  • 如何检查文件是否包含纯文本?

    我有一个装满文件的文件夹 我想搜索其中的一些字符串 问题是有些文件可能是 zip exe ogg 等 我可以以某种方式检查它是什么类型的文件 所以我只打开并搜索 txt PHP 等文件 我不能依赖文件扩展名 使用Python的mimetyp
  • React Native - Expo:fontFamily“SimpleLineIcons”不是系统字体,尚未通过 Font.loadAsync 加载

    所以我在 Android 设备 模拟器上收到此错误 另一方面 在 iOS 上 它编译得很好 并且simple line icons都可以正确显示 我正在运行最新版本的expo 我的package json name FamScore3 ve
  • Rapidjson 使用 JSON 字符串作为编写器的输入进行漂亮打印

    下列的rapidjson 文档 http rapidjson org md doc sax html Writer我能够以逐个键的方式生成漂亮打印的 JSON 输出 例如 rapidjson StringBuffer s rapidjson
  • 如何使用多个 Google 文件选择器处理回电

    如果我在一页上有多个 Google 云端硬盘文件选择器 我该如何处理回调以确保数据传递到正确的部分 我基本上列出了许多项目 每个项目都有一个链接到文件选择器的选择文件按钮 所有示例都只是将数据传递回同一个位置 但我需要每个请求的数据都不同
  • 无法通过 http 克隆 git 存储库;未找到信息/参考文献

    我正在尝试使 git 存储库可通过 http 进行只读访问 我用老式的方式来做 因为git http backend在我的主机系统上不可用 也就是说 我只是将裸存储库放在 http 可访问的位置 我使用以下命令在主机上成功创建了裸存储库gi
  • java - 如何检查日历实例最初是否是错误的日期

    我有一个 Calendar 实例 通过以下方式从 XSD 日期时间解析javax xml bind DatatypeConverter parseDateTime http docs oracle com javase 7 docs api
  • 防止 Vue.js 在慢速客户端上显示括号[重复]

    这个问题在这里已经有答案了 我刚刚做了我的第一个Vue js应用程序 它太棒了 我遇到的唯一问题与慢速连接上的绑定值有关 例如 在我的template我有这个代码 div div class start time event start t
  • 无法从 jcenter 获取新项目的依赖关系[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我无法通过新项目从 jcenter 获取 kotlin pom 我所做的就是转到 文件 gt 新建项目 并创建一个没有任何活动的新
  • 尝试使用 PowerShell 脚本从 Active Directory 中的所有组中删除用户

    我正在尝试使用 PowerShell 脚本根据用户想要从所有组中删除的用户来接受用户的输入 我的语法错误吗 这是我到目前为止所拥有的 User1 Read Host Prompt Enter the username of the empl
  • 发现正在进行的无限循环?

    有没有办法找出当前执行的代码来找出无限循环 我有使用当前源运行的应用程序 我附有 Visual Studio 调试器 我只需要知道代码当前在哪里 以便我可以进一步调试它 如果您从 Visual Studio 运行它 则可以使用代码页中的 暂
  • Selenium Chromedriver 挂起?

    我有一个长时间运行的 python 应用程序 它将定期 每 30 60 秒 打开一个带有 selenium 和 chrome 驱动程序的网页 运行一些 javascript 并截取屏幕截图 它在 Xvfb 中带有 chrome 的 EC2
  • Rust 中使用受限泛型的函数指针

    我正在尝试创建一个如下所示的结构 struct MediaLibrary b where B Ord root dir PathBuf item meta fn String self meta fn String media item f
  • 为什么我收到 StackOverflowError

    public class Category private Category parentCategory private Set
  • 使用 AWS Amplify 部署静态 Svelte-Kit 应用程序

    我正在尝试在 AWS Amplify 上部署我的 Svelte 应用程序 我推送提交 Amplify 构建并验证应用程序 但如果我访问应用程序 URL 它只是一个空白页面 这可能是适配器问题 我尝试了 node js 和静态的 但没有成功
  • 整数 sqrt 的精度

    我有一个这样的循环 for uint64 t i 0 i i