【问题标题】:how does the std::sqrt() function work? [duplicate]std::sqrt() 函数是如何工作的? [复制]
【发布时间】:2017-12-27 00:25:38
【问题描述】:

有人知道 std::sqrt() 函数是如何工作的吗? (或者至少有一个想法?)

我在互联网上看到的方法似乎非常慢,使用了大量的近似值和迭代。

每个人都知道 sqrt() 函数很慢,但我想知道 std 中的那个是如何工作的,所以我可以模糊地知道什么时候避免它是有益的。 (是的,如果我想确定我可以分析,但有一个模糊的想法仍然很好)

编辑:并没有很好地提出这个问题......我感兴趣的是:

  • 最快的计算平方根的 C++ 函数是什么样子的? (或多或少,我只是想知道它背后的实际逻辑)

【问题讨论】:

标签: c++ math std


【解决方案1】:

如今,在现代机器上,浮点函数被传递给硬件(浮点单元或数学协处理器)。

【讨论】:

  • 称它为“协处理器”有点用词不当,你不觉得吗?我已经 20 多年没有看到它从主 CPU 中分离出来了。
  • 这就是我 CMA 并包含“浮点单元”的原因。我敢打赌,您一生中曾经使用过 '286!
【解决方案2】:

有时,它会使用 CPU 提供的功能:

$ cat main.cc
#include <cmath>
#include <ctime>
#include <cstdlib>
int main(){
    srand (clock());
    const double d = rand();
    return std::sqrt(d) > 2 ? 1 : 0;
}

(blahblah 就是这样,没有什么相关的东西被优化掉了,不要运行那个程序!)

$ g++ -S main.cc
$ cat main.s
    .file   "main.cc"
    .text
    .p2align 4,,15
.globl main
    .type   main, @function
main:
.LFB106:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    call    clock
    movl    %eax, %edi
    call    srand
    call    rand
    cvtsi2sd    %eax, %xmm1
    sqrtsd  %xmm1, %xmm0
    ucomisd %xmm0, %xmm0
    jp  .L5
.L2:
    xorl    %eax, %eax
    ucomisd .LC0(%rip), %xmm0
    seta    %al
    addq    $8, %rsp
    .cfi_remember_state
    .cfi_def_cfa_offset 8
    ret
.L5:
    .cfi_restore_state
    movapd  %xmm1, %xmm0
    call    sqrt
    jmp .L2
    .cfi_endproc
.LFE106:
    .size   main, .-main
    .section    .rodata.cst8,"aM",@progbits,8
    .align 8
.LC0:
    .long   0
    .long   1073741824
    .ident  "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
    .section    .note.GNU-stack,"",@progbits

(提示:它正在使用 sqrt-cpu 指令)

【讨论】:

  • 它不只是使用sqrtsd 指令,它还检查结果是否对自身无序(例如,NaN),然后调用实际的如果是这样的话,库函数。不知道为什么需要这样做,可能是为了获取指令本身未提供的额外信息,可能是异常处理?
  • @paxdiablo:既然你这么说,我也想知道。我找不到有关 sqrtsd 指令细节的足够信息。
【解决方案3】:

sqrt();功能在幕后。

它总是检查图表中的中点。 示例:sqrt(16)=4; sqrt(4)=2;

现在,如果您在 16 或 4 内输入任何输入,例如 sqrt(10)==?

它找到 2 和 4 的中点,即 = x ,然后再次找到 x 和 4 的中点(它不包括此输入中的下限)。它一次又一次地重复这个步骤,直到它得到完美的答案,即 sqrt(10)==3.16227766017。它位于 b/w 2 和 4。所有这些内置函数都是使用微积分、微分和积分创建的。

【讨论】:

    【解决方案4】:

    该标准没有指定特定的实现。

    一种选择是查看一个典型的实现,但您可能会发现它是经过高度优化的汇编程序。

    【讨论】:

    • 嗯,我知道,但是假设它使用最快的 C++ 函数来计算它,它会是什么样子?
    • @xcrypt:老实说,我不知道算法库倾向于使用什么。我会看看en.wikipedia.org/wiki/Methods_of_computing_square_roots 以了解其中的一些技术。事实上,它们都依赖于迭代或近似。
    • @xcrypt:由于所有平方根计算算法都基于数值近似,因此更快几乎直接意味着不精确。我怀疑你想找到“最快”的实现。
    猜你喜欢
    • 2012-01-21
    • 1970-01-01
    • 2023-03-21
    • 2021-10-27
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多