我有一段简单的代码,它从FORTRAN生成的REAL数组中提取一个浮点数,然后将其插入流中进行记录。尽管此方法适用于前30种情况,但在31日因“浮点无效操作”而崩溃。

代码是:

int FunctionDeclaration(float* mrSwap)
{
...
float swap_float;
stringstream message_stream;
...
swap_float = *(mrSwap+30-1);
...
message_stream.clear();
message_stream <<  30 << "\t" << swap_float << "\tblah blah blah \t";

调试时,崩溃之前实例的swap_float的值(在上面的最后一行)为1711696.3-除此之外,此值比到目前为止的大多数值都大得多,没有什么特别的。

我也尝试过用cerr替换message_stream,并遇到同样的问题。迄今为止,我一直相信cerr几乎是坚不可摧的-一个简单的浮子怎么能毁掉它?

编辑:

感谢您的评论:我已经添加了mrSwap的声明。 mrSwap大约有200长,所以距离目标还有很长的路要走。它是在我的控制范围之外填充的,可能不会填充单个条目-但据我所知,这仅意味着将swap_float设置为随机浮点数?

最佳答案



重点不是。 IEEE浮点数中的某些位模式表示一个无效数-例如,算术运算溢出的结果或一个无效数(例如0.0/0.0)。令人费解的是,调试器显然将数字视为有效,而cout则不接受。

尝试获取swap_float的位布局。在32位系统上:

int i = *(int*)&swap_float;

然后以十六进制格式打印i,让我们知道您看到了什么。

已更新为添加:根据Mike的评论,i = 1238430338(十六进制为49D0F282)。这是一个有效的浮点数,正好等于1711696.25。恐怕我不知道发生了什么事。我唯一可以建议的是,也许编译器将无效的浮点数直接从mrSwap数组加载到了浮点寄存器组中,而没有通过swapFloat进行加载。因此,swapFloat的真实值根本无法提供给调试器。要检查此,请尝试
int j = *(int*)(mrSwap+30-1);

告诉我们您所看到的。

再次更新以添加:另一种可能性是延迟的浮点陷阱。由于某些非法操作,浮点协处理器(如今已内置在CPU中)会生成浮点中断,但是直到尝试下一次浮点操作时,该中断才会被注意到。因此,此崩溃可能是由于先前的浮点操作(可能在任何地方)导致的。祝你好运...

关于c++ - 输入float到stringstream时的“Floating-point invalid operation”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10515051/

10-09 13:25