C++ &引用;浮点无效操作“;将float输入到stringstream时

C++ &引用;浮点无效操作“;将float输入到stringstream时,c++,floating-point-exceptions,C++,Floating Point Exceptions,我有一段简单的代码,它从FORTRAN生成的实数组中提取一个浮点,然后将其插入到一个流中进行日志记录。虽然这适用于前30种情况,但在31日,它因“浮点无效操作”而崩溃 代码是: int FunctionDeclaration(float* mrSwap) { ... float swap_float; stringstream message_stream; ... swap_float = *(mrSwap+30-1); ... message_stream.clear(); message_

我有一段简单的代码,它从FORTRAN生成的实数组中提取一个浮点,然后将其插入到一个流中进行日志记录。虽然这适用于前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";
int函数声明(float*mrSwap)
{
...
浮点数交换浮点数;
stringstream消息流;
...
交换浮点数=*(mrSwap+30-1);
...
消息流清除();
消息流
可能不会填充单个条目,但请尽我所能
要理解,这只意味着swap_float将被设置为
随机浮动

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

尝试获取
交换浮点数的位布局。在32位系统上:

int i = *(int*)&swap_float;
然后用十六进制打印
i
,让我们知道您看到了什么

更新为添加:根据Mike的评论,i=1238430338,十六进制为49D0F282。这是一个有效的浮点数,正好等于1711696.25。因此我恐怕不知道发生了什么。我唯一能建议的是,编译器可能直接从
mrSwap
数组放入浮点寄存器组,而不经过
swapFloat
。因此
swapFloat
的真实值对于调试器来说根本不可用。若要检查此情况,请尝试

int j = *(int*)(mrSwap+30-1);
告诉我们你看到了什么


再次更新以添加:另一种可能是延迟的浮点陷阱。浮点协处理器(最近内置于CPU中)由于某些非法操作而生成浮点中断,但在尝试下一个浮点操作之前,中断不会被注意到。因此,此崩溃可能是上一个浮点操作的结果,可能在任何位置。祝您好运…

我只是添加此答案以突出显示正确的sol以上TonyK回答中的问题-因为我们做了一些循环,答案已经编辑,并且由于评论中有几个要点,实际答案可能不会立即显现。所有解决方案都应该归功于TonyK

“另一种可能是延迟浮点陷阱。浮点协处理器(现在内置于CPU中)由于某些非法操作而生成浮点中断,但在尝试下一个浮点操作之前,中断不会被注意到。因此,此崩溃可能是上一个浮点操作的结果,该操作可能在任何位置。”-TonyK


这确实是个问题:在我使用IsSame进行比较时,另一个值是NaN(在本文中这是一个有效值),虽然它很高兴地从swap_float中减去了它,但它在“报告下一个操作为错误”中加了一个标志。我必须说,我完全不知道这是可能的-我认为如果它成功了,它就成功了。

你能把这作为一个可编译的小例子吗?什么是
mrSwap
以及它是如何填充的?听起来像你是在说我已经溢出了结尾。如果这是一个指针操作,我想知道您是否刚刚运行过数组的结尾。我确信cerr没有问题。您引用了
mrSwap
,但没有显示它是什么。您尝试过使用
printf()吗
而不是
cout
?谢谢Tony-值得了解浮动。当我按照你的建议做时,我在调试器中的I=1238430338,当发送到cerr时。我将尝试用十六进制打印它…好的,十六进制,I=49d0f282。我还尝试使用printf(“%f”,swap\u float),这与完全相同的错误完全相同。在第一次编辑之后,j=49d0f282-与之前相同。在第二次编辑中:这听起来似乎令人不快,因为调试器似乎最终处于“混乱”状态-堆栈的第二项是:“[下面的帧可能不正确和/或丢失,没有为ntdll.dll加载符号]”。不幸的是,我没有使用调试器的经验,所以我可能没有得到所有的线索…但是,我知道以前的浮点操作是什么。我代码段中的最后一组“…”实际上是对这个函数的调用:bool IsSame(float swap_值,double function_值,double tolerance){return(abs(swap_值-(float)函数_value)