c++天花板函数的奇怪结果
Strange results with C++ ceiling function
我一直在尝试天花板函数,并得到一些奇怪的结果。如果我对一个十进制数乘以100进行顶数运算,就会得到一个确定的结果。但是,如果我直接对乘法的结果执行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
尝试将变量a
的类型从float
更改为double
,再次查看结果
来自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++,所以后面是a名义回答。
答案:浮点数是an近似。IEEE标准32位浮点数支持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。双Type提供更高的精度(53位)尾数)。
同样,参见[29.17]为什么我的浮点比较不起作用?
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
。
还要注意乘法也不是精确的
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- valgrind-hellgrind与泄漏检查的结果不同
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 序列化,没有库的整数,得到奇怪的结果
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 在更改for循环的第三部分后,未使用for循环结果
- 使用++运算符会导致意外的结果
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- C++Brute Force攻击函数不会返回结果
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 算术运算的结果类似于:C浮点变量中的1/3
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 密码登录程序将永远循环并显示不正确的结果
- 如何让C++'tally up'结果并制定计划?
- 为什么这个程序的结果是3 "born"?和 4 死
- c++天花板函数的奇怪结果