首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有sin()和sinf()的浮点值

带有sin()和sinf()的浮点值
EN

Stack Overflow用户
提问于 2014-05-04 11:13:34
回答 1查看 1.1K关注 0票数 1

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

我使用的是g++ (Ubuntu/Linaro4.6.3-1ubuntu5) 4.6.3。我使用-O0来禁用优化。

背景:我在程序中跟踪一个bug,在这个程序中,我需要在整个程序中使用float,因为它将被移植到一个嵌入式系统中。然而,我目前正在Ubuntu上调试我的PC仅仅是因为它是方便的。我发现当x很小时,像(x-s)这样的操作会导致不准确。这让我觉得这一定是因为灾难性的取消造成了重大数字的损失。但是,当我用sinf(x)替换变量s时,没有出现不准确的问题(如(2)和(3)中所示)。我可以猜测sinf()可能被实现为和sin()相同的东西。如果是,为什么显式抛出浮点没有效果,如(4)和(5)。现在我很困惑。

代码语言:javascript
运行
复制
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;
} 

这是输出:

代码语言:javascript
运行
复制
$ 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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-04 12:25:17

在C++中,sin有一个重载的float sin(float f)。重载解析是对参数类型执行的,而不是返回类型。要强制使用double sin(double d),您需要转换参数:sin(static_cast<double>(x))

(2) vs (3):FP标准允许实现以比最终结果更高的精度存储中间结果。因此,s的值不一定与(3)中sin(f)的中间结果完全相同。

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

代码语言:javascript
运行
复制
( 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
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23455545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档