为什么 std::round(sin(pi/6)) 不等于 1?
Why does std::round(sin(pi/6)) not equal 1?
cpp首选项文档指出,std::round将在"中间情况下"专门从零四舍五入。虽然文字0.5
是这样,但std::sin(pi/6)
却不是这样。我认为这可能是浮点错误,所以我打印了值,但它正好0.5
.但是,在检查二进制表示后,我可以看到它们确实以不同的方式表示。我在下面提供了用于进行这些检查的代码。
#include <iostream>
#include <stdio.h>
#include <cmath>
int main(int argc, char * argv[])
{
double const pi = std::acos(-1);
double const a = std::sin(pi/6);
double const b = 0.5;
std::cout << "round(" << a << ") = " << std::round(a) << "n";
auto pa = reinterpret_cast<const unsigned char *>(&a);
auto pb = reinterpret_cast<const unsigned char *>(&b);
std::cout << "a = 0x";
for (size_t i = 0; i != sizeof(double); ++i) {
printf("%02x", pa[i]);
}
std::cout << "nb = 0x";
for (size_t i = 0; i != sizeof(double); ++i) {
printf("%02x", pb[i]);
}
std::cout << "n";
}
round(0.5) = 0
round(0.5) = 1
a = 0xffffffffffffdf3f
b = 0x000000000000e03f
所以我的问题是这种舍入行为是 c++ 规范的一部分还是这是一个错误?无论如何,是否有一些通用方法可以"纠正"sin
返回的值的表示形式?我不确定它是什么格式,因为根据我对 IEEE-754 的了解,它看起来应该是 NaN。虽然据我了解,c++ 不能保证 IEEE-754 浮点表示?
问题是您没有打印具有足够有效数字的值。 当我用std::setprecision(20)
提高精度时,我得到:round(0.49999999999999994449) = 0
。
您可以通过更改代码或在此在线计算器的底部十六进制字段中输入3fdfffffffffffff
来亲自查看以下内容:https://baseconvert.com/ieee-754-floating-point
表示形式看起来像 NaN,因为您正在向后读取它。 x86/x64 具有小端浮点数。所以你应该读到它从高到低地址,产生0x3fdfffff...
,这当然略小于0.5。
相关文章:
- 为什么 std::round(sin(pi/6)) 不等于 1?
- 你怎么编码,如果x不等于一个数字,程序就会退出
- u张量模型输出不等于预期输出
- 虽然不等于陈述和/或差异
- 这种关系不等于定义良好的表达式吗?
- 为什么我的程序不近似Pi
- OpenGL 版本不等于支持的着色器版本
- 两个 4 位位字段加起来不等于一个字节的大小 - 如何修复?
- 为什么这收敛到 3 而不是 pi
- 如果整数不等于 0,则将其减小为 1
- C 循环虽然不等于任何两个值
- vb.net单不等于c float
- 如何获取C编译器#Error如果大小(struct ..)不等于给定的数字
- C++ 而语句不等于检查
- 有没有办法检查int是否不等于数组中的所有值?(C )
- 整数数组中的元素数量不等于其大小
- 获取不等于特定值的向量的第一个N元素
- 使用 boost 解析符号链接时,结果不等于原始路径名
- 什么是有效的检查:等于或不等于
- 发送的字节不等于C 套接字PRG中的接收字节