世界上有三种人:第一种人知道他们不明白浮点运算(他们是正确的);第二种人以为他们明白浮点运算(他们是错误的);少数真正的专家期望有朝一日能够理解浮点运算(他们是明智的)。
by Herb Scutter in Exceptional C++ Style
最近在用模型进行实验的时候发现一个奇怪的现象:在读取个别模型里点的坐标值时程序出错。出错地方的有类似下面的代码如下:
ifstream file;
file.open(FileName,ios::in);
……
while(!file.eof()) {
float tmpf;
file>>tmpf;
m_triset.push_back(tmpf);
……
其中m_triset是一个vector容器,错误类型为非法读写。然后定位到vector下的end()函数。开始以为是vector的问题,可vector是专家推荐的标准容器,可用性方面不应该出现问题。如果是数据问题的话那为什么其他数据不出错,单单个别有问题?经过排查,定位到了出错的数据行:
-13.861162621176337 -0.22618263122478108 27.2560531379693
错误出现在读取第二个错的时候,这个时候问题似乎明朗了:第二个数小数点后的位数太多了,删掉几位之后果然就通过了。但是下面又遇到了类似的数,程序再次报错推出。
怎么办?总不能把所有的数据都改一遍吧。现在错误已经与vector无关了,是由于ifstream读取的时候出的问题。但又看不到其内部的实现,所以考虑换成fscanf之类其他函数试试。正准备改,突然发现tmpf类型是float,随手改成double之后程序顺利运行。
看来又是浮点数惹得祸?
MSDN中对float和double范围有如下描述:
float 4Bytes Range of Values: 3.4E +/- 38 (7 digits)
double 8Bytes Range of Values: 1.7E +/- 308 (15 digits)
没有评论:
发表评论