使用C ++上限功能的奇怪结果

时间:2011-04-06 06:53:35

标签: c++ ceil

我一直在尝试天花板功能并且得到了一些奇怪的结果。如果我对十进制数乘以百分比执行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

3 个答案:

答案 0 :(得分:9)

这里的问题是计算机无法可靠地表示浮点数。这意味着,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,请参阅the result again

答案 1 :(得分:5)

来自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 ++,接下来是一个   名义答案。

     

回答:浮点数是   近似。 IEEE标准   32位浮点数支持1位符号,8位   指数位,和23位   尾数。自标准化   二进制点尾数总是有   形式1.xxxxx ...领先1是   掉线,你得到有效24   尾数位。数字1000.43   (以及许多其他人,包括一些人   真正常见的像0.1)不是   在float或。中完全可以表示   双格式。实际上是1000.43   表示如下   bitpattern(“s”表示位置   标志位,“e”显示   指数位的位置,和   “m”显示了这个位置   尾数位):

 seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
 01000100011110100001101110000101
     

转移的尾数是   1111101000.01101110000101或1000 + 7045/16384。小数部分是   0.429992675781。使用24位尾数,您只能获得约1份   浮子精度16M。双   type提供更高的精度(53位   尾数)。

另请参阅[29.17] Why doesn't my floating-point comparison work?

答案 2 :(得分:1)

ceil(x)函数返回的最小整数不小于x

由于您键入的常量(如4.111.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

另请注意,乘法也不准确。