我有一个简单的代码提取来自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是非常indestructable - 一个简单的浮动怎么能摧毁它?
编辑:
感谢您的意见:我已经添加mrSwap的声明。 mrSwap约为200长,所以我是一个很长的路要走结束。 这是我的填充控制之外,并且可能不被填充单个条目-但求最好的我的理解,这将仅仅意味着swap_float将被设置为随机浮动?
各个条目可能不被填充 - 但求最好的我的理解,这将仅仅意味着swap_float将被设置为随机浮动?
显然不是。 在IEEE浮点数某些位模式指示无效数目 - 例如,溢流算术运算的结果,或无效的一个(如0.0 / 0.0)。 这里的令人费解的是,调试器显然是可接受的有效数量,同时cout
没有。
尝试获得的位布局swap_float
。 在32位的系统:
int i = *(int*)&swap_float;
然后打印i
在十六进制,并让我们知道你所看到的。
更新补充:从迈克的评论,我= 1238430338,这是十六进制49D0F282。 这是一个有效的浮点数,等于准确1711696.25。 所以,我不知道发生了什么事情,我害怕。 我可以建议的唯一的事情是,也许编译器直接从加载无效浮点数mrSwap
阵列到浮点寄存器组,而无需通过去swapFloat
。 所以真正价值swapFloat
根本就没有提供给调试器。 要检查这个问题,尝试
int j = *(int*)(mrSwap+30-1);
并告诉我们你看到了什么。
再次更新补充:另一种可能性是延迟浮点陷阱。 浮点协处理器(内置于CPU,这些天)产生的浮点中断,因为一些非法操作,但中断不会被注意到,直到下一个浮点运算尝试。 所以这暴跌可能是以前的浮点运算,它可以在任何地方的结果。 祝你好运...
我只是加入这个答案突出上述TonyK的回答中正确的解决方案 - 因为我们做了几个圈,答案已经被编辑,因为几个要点是注释中,实际的答案可能不会立即显现。 所有信贷应该去TonyK的解决方案。
“另一种可能性是延迟浮点陷阱。浮点协处理器(内置于CPU,这些天)产生的浮点中断,因为一些非法操作,但中断不会被注意到,直到下一个浮动-点操作尝试。因此,这坠毁可能是以前的浮点运算,它可以在任何地方的结果。” - TonyK
这的确是问题:在使用IsSame我的比较,其他值为NaN(而这是这方面的一个有效值),虽然它高兴地从swap_float减去它,它把一个标志说,报告的下一个操作的错误。 我不得不说,我完全不知道这是可能的 - 我想,如果它的工作,它的工作。