gpt4 book ai didi

c++ - sin() 和 sinf() 的浮点值

转载 作者:行者123 更新时间:2023-11-30 02:46:33 25 4
gpt4 key购买 nike

为什么我从 sin(x) 和 sinf(x) 得到的值与下面的 (8) 和 (9) 相同?为什么我从下面的 (2) 和 (3) 两个不同的实现中得到不同的 [ x - sinf(x) ] 值?为什么 (6) 给出与 (5) 相同的结果?

我正在使用 g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3。我使用 -O0 来禁用优化。

背景:我正在追踪我的程序中的一个错误,我需要在整个程序中使用 float,因为它将被移植到嵌入式系统。但是,我目前在我的 PC 上调试 Ubuntu,只是因为它很方便。我发现像 (x-s) 这样的操作在 x 很小的时候会导致不准确。这让我认为这一定是由于灾难性取消导致重要数字丢失。然而,当我用 sinf(x) 替换变量 s 时,不准确的问题并没有发生(如(2)与(3)所示)。我猜想 sinf() 的实现可能与 sin() 相同。如果是这样,为什么像 (4) 和 (5) 那样显式转换为 float 没有效果。现在我很困惑。

int main()
{
unsigned long int xx(0x3d65c2f2);
float x(*reinterpret_cast<float*>(&xx));
float s(sinf(x));

printf("( 1) x = %.10e\n", x);
printf("( 2) x - s = %.10e\n", x-s);
printf("( 3) x - sinf(x) = %.10e\n", x-sinf(x)); // Why is it different from (2)?
printf("( 4) x - float(sinf(x)) = %.10e\n", x-float(sinf(x))); // Compare with (3). Why casting has no effect?
printf("( 5) float(x) - float(sinf(x)) = %.10e\n", float(x)-float(sinf(x))); // Compare with (3). Why casting has no effect?
printf("( 6) x - sin(x) = %.10e\n", x - sin(x));

printf("( 7) s = %.10e\n", s);
printf("( 8) sinf(x) = %.10e\n", sinf(x));
printf("( 9) sin(x) = %.10e\n", sin(x)); // Compare with (8). Is sinf() identical to sin()?
printf("(10) float(sinf(x)) = %.10e\n", float(sinf(x))); // Compare with (8). Why casting has no effect?

double s_df(sinf(x));
double s_dd(sin(x));
float s_fd(sin(x));
float s_ff(sinf(x));
printf("(20) s_df = %.10e\n", s_df);
printf("(21) s_dd = %.10e\n", s_dd); // Compare with (20). Is sinf() identical to sin()?
printf("(22) s_fd = %.10e\n", s_fd);
printf("(23) s_ff = %.10e\n", s_ff);

return 0;
}

这是输出:

$ make && ./main
g++ main.cc -Wall -c -o main.o -O0
g++ -o main main.o
( 1) x = 5.6094117463e-02
( 2) x - s = 2.9411166906e-05
( 3) x - sinf(x) = 2.9412529899e-05
( 4) x - float(sinf(x)) = 2.9412529899e-05
( 5) float(x) - float(sinf(x)) = 2.9412529899e-05
( 6) x - sin(x) = 2.9412529899e-05
( 7) s = 5.6064706296e-02
( 8) sinf(x) = 5.6064704933e-02
( 9) sin(x) = 5.6064704933e-02
(10) float(sinf(x)) = 5.6064704933e-02
(20) s_df = 5.6064704933e-02
(21) s_dd = 5.6064704933e-02
(22) s_fd = 5.6064706296e-02
(23) s_ff = 5.6064706296e-02

最佳答案

在 C++ 中,sin有过载 float sin(float f) .重载决议是根据参数类型而不是返回类型完成的。强制使用double sin(double d)你需要转换参数:sin(static_cast<double>(x)) .

(2) vs (3):FP 标准允许实现以比最终结果更准确的方式存储中间结果。所以 s 的值不必与 sin(f) 的中间结果完全相同在 (3) 中。

这在很大程度上取决于您的编译器、编译器设置和硬件。例如,如果我在我的系统上运行您的代码,我会得到:

( 1) x                         = 5.6094117463e-02
( 2) x - s = 2.9411166906e-05
( 3) x - sinf(x) = 2.9411166906e-05
( 4) x - float(sinf(x)) = 2.9411166906e-05
( 5) float(x) - float(sinf(x)) = 2.9411166906e-05
( 6) x - sin(x) = 2.9412529899e-05
( 7) s = 5.6064706296e-02
( 8) sinf(x) = 5.6064706296e-02
( 9) sin(x) = 5.6064704933e-02
(10) float(sinf(x)) = 5.6064706296e-02
(20) s_df = 5.6064706296e-02
(21) s_dd = 5.6064704933e-02
(22) s_fd = 5.6064706296e-02
(23) s_ff = 5.6064706296e-02

关于c++ - sin() 和 sinf() 的浮点值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23455545/

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