繁体   English   中英

为什么相同数字的 sin 会返回两个截然不同的值?

[英]Why does sin of the same number return two very different values?

有人可以解释为什么这两个输出有很大不同吗?

当我打印出(float)direction*PI/180.0ftheta时,它们都按预期评估为 1.5708。 为什么在将其放入sin function 之前将其放入浮点变量会在 output 中产生如此巨大的差异? 另请注意, test2返回正确答案 (1),而test返回错误答案 (0)。

#include <iostream>
#include <cmath>

#define PI 3.14159265


int main()
{   
    int direction = 90;
    float theta = (float)direction*PI/180.0f;
    int test =  (int)sin(theta);
    int test2 = (int)sin((float)direction*PI/180.0f);
    
    std::cout << theta << " " << (float)direction*PI/180.0f << " " << test << " " << test2;
}

(float)direction*PI/180.0f使用double精度运算。 PIdouble文字,因为它没有f后缀。 其他两个操作数( (float)direction180.0f )是float s,是的,但它们只是被提升为double (并且转换在 IEEE 浮点数中是精确的)。 请注意,由于运算符的优先级, (float)仅适用于direction 对于test2 ,您将生成的double精度值直接传递给sin ,而sin恰好返回1 对于test ,首先将double向下转换为float赋值给theta ,然后将其向上转换为double以调用sin (请注意,您调用的是 C 的double sin(double) ,而不是 C++ 的float std::sin(float) )。 通过演员表, theta失去了一点四舍五入的价值。 然后sin相应地给出一个略小于1的值,然后在转换为int时一直舍入到0 如果您调用了std::sin ,那么您会得到1 ,因为std::sin会将略小于1double舍入为float ,这将给出1 (与截断为int不同)。

像这样将浮点值打印到std::cout对调试浮点没有用,因为值会四舍五入。 我喜欢使用std::hexfloat ,它显示真正的二进制值(转换为十六进制),而不是十进制。 我还摆脱了PI ,将 C 风格的转换变成了函数式的转换,以更清楚地显示发生了什么。 我已经将testtest2变成了double s( sin的返回类型)所以我们可以真正地看看它们。

int main() {
    int direction = 90;
    float theta = float(direction)*3.14159265/180.0f;
    double test1 = sin(theta);
    double test2 = sin(float(direction)*3.14159265/180.0f);
    std::cout << std::hexfloat;
    std::cout << theta << " " << float(direction)*3.14159265/180.0f << "\n";
    std::cout << test1 << " " << test2 << "\n";
}

神马

它给

0x1.921fb6p+0 0x1.921fb53c8d4fp+0
0x1.ffffffffffff7p-1 0x1p+0

这巧妙地向我们展示了我们在test2中使用的值比theta有更多的数字,因为它是double精度但float theta 您还看到test1几乎是1 ,但不完全是。

舍入误差。 您的测试变量 < 1.0,您的 test2 变量 >= 1.0。 I C 和 C++,0.9999999999999 四舍五入为 0。

#include <iostream>
#include <cmath>

#define PI 3.14159265


int main()
{   
    int direction = 90;
    float theta = (float)direction*PI/180.0f;
    auto test =  sin(theta);
    auto test2 = sin((float)direction*PI/180.0f);
    
    std::cout << theta << " " << (float)direction*PI/180.0f << " " << (int) test << " " << (int) test2 << std::endl;
    std::cout <<std::boolalpha << "test >= 1.0 = " << (test >= 1.0) << std::endl;
    std::cout << "test2 >= 1.0 = " << (test2 >= 1.0) << std::endl;
    std::cout << "test == test2 = " << (test == test2) << std::endl;
    std::cout << "test < test2 = " << (test < test2) << std::endl;
}

Output:

1.5708 1.5708 0 1
test >= 1.0 = false
test2 >= 1.0 = true
test == test2 = false
test < test2 = true

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM