[英]Strange results with C++ ceiling function
我一直在尝试天花板功能,并得到了一些奇怪的结果。 如果我对十进制数乘以百分比执行ceil操作,我得到一定的结果。 但是如果我直接对该乘法的结果执行ceil,我得到一个完全不同的输出。 另一个转折是这些不同的结果仅出现在某些数字上。 任何帮助,将不胜感激。
#include <stdio.h>
#include <cmath>
int main ()
{
cout << "The ceiling of " << 411 << " is " << ceil(411) << endl;
cout << "The ceiling of 4.11*100 is " << ceil(4.11*100) << endl;
cout << "The ceiling of " << 121 << " is " << ceil(121) << endl;
cout << "The ceiling of 1.21*100 is " << ceil(1.21*100) << endl;;
}
OUTPUT:
The ceiling of 411 is 411
The ceiling of 4.11*100 is 412
The ceiling of 121 is 121
The ceiling of 1.21*100 is 121
这里的问题是计算机无法可靠地表示浮点数。 这意味着, 4.11
并不表示为4.11
,而是非常接近它。 当这个“非常接近4.11”的数字乘以100
,产品的ceil
结果为412
,这让你大吃一惊! 但是一旦你知道如何存储和检索浮点数,它就不足为奇了。
看看这个有趣的演示:
float a = 3.2; //3.2 is double!
if ( a == 3.2 )
cout << "a is equal to 3.2"<<endl;
else
cout << "a is not equal to 3.2"<<endl;
float b = 3.2f; //3.2f is a float. Note: f is appended to make it float!
if ( b == 3.2f )
cout << "b is equal to 3.2f"<<endl;
else
cout << "b is not equal to 3.2f"<<endl;
输出:
a不等于3.2
b等于3.2f
请在ideone上进行实验: http : //www.ideone.com/pAGzM
来自FAQ :
[29.16]为什么浮点数如此不准确? 为什么不打印0.43?
#include <iostream> int main() { float a = 1000.43; float b = 1000.0; std::cout << a - b << '\\n'; ... }
免责声明 :使用舍入/截断/近似的挫折并不是真正的C ++问题; 这是一个计算机科学问题。 但是,人们一直在comp.lang.c ++上询问它,所以接下来是一个名义上的答案。
答 :浮点是近似值。 用于32位浮点的IEEE标准支持1位符号,8位指数和23位尾数。 由于标准化的二进制点尾数始终具有1.xxxxx的形式...前导1被丢弃并且有效地获得24位尾数。 数字1000.43(以及许多其他数据,包括一些非常常见的数字,如0.1)在浮点数或双精度格式中并不完全可表示。 1000.43实际上表示为以下位模式(“s”表示符号位的位置,“e”表示指数位的位置,“m”表示尾数位的位置):
seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm 01000100011110100001101110000101
移位的尾数是1111101000.01101110000101或1000 + 7045/16384。 小数部分是0.429992675781。 使用24位尾数,您只能得到大约1个16M精度的浮点数。 double类型提供更高的精度(53位尾数)。
ceil(x)
函数返回不小于x
的最小整数。
由于您键入的常数(如4.11
或1.21
)未精确表示 - 它们可能恰好用较小的数字或稍大的数字表示,或者在极少数情况下具有相同的数字。 例如,你的编译器将常数4.11
表示为略大的数字,因此4.11*100
恰好略大于411,因此ceil(4.11*100) == 412
(因为412是最小数量不小于略大于411的数字),但1.21
表示为略小的数字,因此1.21*100
略小于121所以ceil(1.21*100)==121
。
另请注意,乘法也不准确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.