gpt4 book ai didi

c++ - pow(a/b,x) 与 pow(b/a,-x) 的数值精度

转载 作者:可可西里 更新时间:2023-11-01 17:53:06 41 4
gpt4 key购买 nike

pow(a/b,x)pow(b/a,-x) 在精度上有区别吗?如果存在,将小于 1 的数字提升为正幂或将大于 1 的数字提升为负幂会产生更准确的结果吗?

编辑:让我们假设 x86_64 处理器和 gcc 编译器。

编辑:我尝试使用一些随机数进行比较。例如:

printf("%.20f",pow(8.72138221/1.761329479,-1.51231)) // 0.08898783049228660424
printf("%.20f",pow(1.761329479/8.72138221, 1.51231)) // 0.08898783049228659037

因此,看起来存在差异(尽管在这种情况下微不足道),但也许了解算法实现的人可以评论最大差异是什么,以及在什么条件下。

最佳答案

这是回答此类问题的一种方法,以了解 float 的行为方式。这不是分析此类问题的 100% 正确方法,但它提供了一个总体思路。

让我们生成随机数。以浮点精度计算 v0=pow(a/b, n)v1=pow(b/a, -n)。并以 double 计算 ref=pow(a/b, n),并将其四舍五入为 float 。我们使用 ref 作为引用值(我们假设 double 的精度比 float 高得多,所以我们可以相信 ref 可以被认为是最佳可能值。这是真的大部分时间用于 IEEE-754)。然后求和 v0-refv1-ref 之间的差异。差值应该用“v和ref之间的 float 个数”来计算。

请注意,结果可能取决于 abn 的范围(以及随机生成器的质量。如果这真的很糟糕,它可能会给出有偏见的结果)。在这里,我使用了 a=[0..1]b=[0..1]n=[-2..2] 。此外,这个答案假设float/double division/pow的算法是同类的,具有相同的特性。

对于我的电脑,求和的差异是:2604828 2603684,这意味着两者之间没有显着的精度差异。

这是代码(注意,这段代码假定 IEEE-754 算法):

#include <cmath>
#include <stdio.h>
#include <string.h>

long long int diff(float a, float b) {
unsigned int ai, bi;
memcpy(&ai, &a, 4);
memcpy(&bi, &b, 4);
long long int diff = (long long int)ai - bi;
if (diff<0) diff = -diff;
return diff;
}

int main() {
long long int e0 = 0;
long long int e1 = 0;
for (int i=0; i<10000000; i++) {
float a = 1.0f*rand()/RAND_MAX;
float b = 1.0f*rand()/RAND_MAX;
float n = 4.0f*rand()/RAND_MAX - 2.0f;

if (a==0||b==0) continue;

float v0 = std::pow(a/b, n);
float v1 = std::pow(b/a, -n);
float ref = std::pow((double)a/b, n);

e0 += diff(ref, v0);
e1 += diff(ref, v1);
}

printf("%lld %lld\n", e0, e1);
}

关于c++ - pow(a/b,x) 与 pow(b/a,-x) 的数值精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55586387/

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