Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将float转换为int时的奇怪行为_C++_Casting - Fatal编程技术网

C++ 将float转换为int时的奇怪行为

C++ 将float转换为int时的奇怪行为,c++,casting,C++,Casting,我有一个读取csv文件的类,其中包含小数点后不超过两位数的数字记录 int ReadCellWithFloat(int cellNumber, int multiplier) throw (FSByFieldException) { GoToCell( cellNumber ); float number; FileStream >> number; std::cout << "what we've got: " << number;

我有一个读取csv文件的类,其中包含小数点后不超过两位数的数字记录

int ReadCellWithFloat(int cellNumber, int multiplier) throw (FSByFieldException)
{
    GoToCell( cellNumber );
    float number;
    FileStream >> number;
std::cout << "what we've got: " << number;
    if ( !FileStream.good() )
    {
        throw BuildException( FSByFieldException::NOT_FLOAT );
    }
    while ( multiplier-- )
    {
        number *= 10;
    }
std::cout << ' ' << number << ' ' << (int) number << std::endl;
    PassCell(); // here meaning pass comma separator
    return (int) number;
}

为什么转换为整数时849会转换为848以及如何修复它?

849会转换为848,因为纯转换只会截断该值。所以
(int)4.8
==4。您可能认为
8.49*10*10
是849,但这不一定是真的:)它与架构所能表示的849一样接近,内部可能类似于848.99999。。。一旦被截断,它就会变成848


要修复它,您可以使用
(int)round(number)
,您可能还想看看
ceil()
floor()
函数,以及有关浮点精度问题的一般信息,为了避免在数字比较等方面遇到麻烦。

数字
8.49
无法精确表示,因此,当您将其乘以
10
两次时,您会得到更像
848.99999
,当我尝试此方法时:

number = 8.49 ;
number *= 10 ;
number *= 10 ;

std::cout << std::fixed << number << std::endl ;

在C++11中,您只需使用
round

这是因为浮点数是如何存储在二进制空间中的。这将显示8.49的值最好表示为8.4899997的浮点值

因此,当您将浮点转换为int时,它将解析浮点的实际值,而不是舍入值

有几种方法可以解决此问题: 1) 使用双精度(这将消除此问题,而不是消除它) 2) 使用数学库将数字848.99四舍五入。
3) 将所有数字加上0.5,然后再将其转换为整数。

请参阅此问题在中被问了数百次SO@RaymondChen我是从审查队列来到这里的,但考虑到另一个问题是关于C#的,它真的是重复的吗?原理是一样的,是的。我不熟悉任何围绕浮动的铸造实现;据我所知,这总是千真万确的。你说得对。我同意它总是截断。对不起,如果我的回答有任何地方让人困惑。我对这个问题的解决办法是在使用int(比如(int)(849.99997+0.5))之前,在数字上加上0.5。这样,您就可以避免为这个简单的任务包含数学库。数字849是完全可以表示的。问题在于8.49而不是849。@RaymondChen这确实是一个措词笨拙的问题,我修改了它以澄清它,尽管这个例子确实澄清了我的意思。
number = 8.49 ;
number *= 10 ;
number *= 10 ;

std::cout << std::fixed << number << std::endl ;
std::cout << std::fixed << roundf(number) << std::endl ;