gpt4 book ai didi

c - 这个单精度运算的结果是如何四舍五入的? [或者为什么这个位是 1 而不是 0?]

转载 作者:太空狗 更新时间:2023-10-29 15:07:36 27 4
gpt4 key购买 nike

我正在研究函数优化例程(Nelder-Mead 算法的变体),它在非常特定的条件下无法收敛。

我已经确定一个 float 变量,我们称它为 a,被赋予 a 和另一个变量 之间的平均值>b 与它只有一点不同。

更准确地说,每个变量的值如下:

float a = 25.9735966f; // 41CFC9ED
float b = 25.9735947f; // 41CFC9EC

现在我正在尝试将 ab 之间的平均值分配给 a:

a = 0.5 * (a+b);

当我在测试程序中编写这段代码时,我得到了我想要的结果,即25.9735947。但是在我的原始库代码的调试器中,我看到 a 的值仍然是 25.9735966。我很确定我在这两个程序上有相同的编译器标志。 为什么这种单精度计算会产生不同的结果?

更新

正如@PascalCuoq 所要求的,我认为这是相关行的程序集。尽管这条线还在做其他一些事情,但我不确定乘法发生在哪里。

.loc 1 53 0 discriminator 2
movl -60(%rbp), %eax
cltq
salq $3, %rax
addq -88(%rbp), %rax
movq (%rax), %rax
movl -44(%rbp), %edx
movslq %edx, %rdx
salq $2, %rdx
leaq (%rax,%rdx), %rcx
movl -44(%rbp), %eax
cltq
salq $2, %rax
addq -72(%rbp), %rax
movl -60(%rbp), %edx
movslq %edx, %rdx
salq $3, %rdx
addq -88(%rbp), %rdx
movq (%rdx), %rdx
movl -44(%rbp), %esi
movslq %esi, %rsi
salq $2, %rsi
addq %rsi, %rdx
movss (%rdx), %xmm1
movl -52(%rbp), %edx
movslq %edx, %rdx
salq $3, %rdx
addq -88(%rbp), %rdx
movq (%rdx), %rdx
movl -44(%rbp), %esi
movslq %esi, %rsi
salq $2, %rsi
addq %rsi, %rdx
movss (%rdx), %xmm0
addss %xmm1, %xmm0
movss .LC6(%rip), %xmm1
mulss %xmm1, %xmm0
movss %xmm0, (%rax)
movl (%rax), %eax
movl %eax, (%rcx)

澄清

我的代码是 Numerical Recipes 中 Nelder-Mead 代码的 ripoff 变体。违规行是这一行:

p[i][j]=psum[j]=0.5*(p[i][j]+p[ilo][j]);

在这一行中,p[i][j] == 25.9735966fp[ilo][j] == 25.9735947fp[i][j] 中的结果值为 25.9735966f

最佳答案

我刚刚重读了 IEEE 754-1985 的相关部分,假设您的浮点实现符合该标准。唯一想到的是你的两个环境中有不同的舍入模式。这些是可能性:

  • 舍入到最近,并且在距离相等的情况下:将最低有效位设置为零 => 25.9735947f
  • +INF 舍入 => 25.9735966f
  • 0 舍入 => 25.9735947f
  • -INF 舍入 => 25.9735947f

所以唯一的可能性是你的调试环境有舍入模式towards +INF。对我来说,没有其他合理的解释。

关于c - 这个单精度运算的结果是如何四舍五入的? [或者为什么这个位是 1 而不是 0?],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7934187/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com