“浮点无效操作”当输入float到stringstream时 [英] "Floating-point invalid operation" when inputting float to a stringstream
问题描述
我有一段简单的代码,从一个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几乎是不可破坏的 - 一个简单的浮点怎么能破坏它?
编辑:
$ b $感谢您的意见:我添加了mrSwap的声明。 mrSwap大约是200长,所以我很远的结束。它填充在我的控制之外,并且个人条目可以不填充 - 但是据我的理解,这只是意味着swap_float将被设置为随机浮动?
个人条目可能未填充 - 但是最好的我的
理解,这只是意味着那么swap_float将被设置为
随机浮动?
IEEE浮点数中的某些位模式表示无效数字 - 例如,溢出算术运算的结果,或无效的数(例如0.0 / 0.0)。这里的令人困惑的是,调试器显然接受数字作为有效,而 cout
不。
获取 swap_float
的位布局。在32位系统上:
int i = *(int *)& swap_float;
然后以十六进制打印 i
mrSwap
数组加载无效浮点数到浮点寄存器组,而不通过 swapFloat
。因此, swapFloat
的真实值根本不可用于调试器。要检查这一点,请尝试 int j = *(int *)(mrSwap + 30-1);
并告诉我们您看到了什么。
再次更新以添加:另一种可能是延迟浮点陷阱。由于某些非法操作,浮点协处理器(内置在CPU中)会产生浮点中断,但直到下一个浮点操作尝试。因此,此崩溃可能是之前的浮点操作的结果,可能在任何地方。祝你好运...
I have a simple piece of code that extracts a float from a FORTRAN-generated REAL array, and then inserts it into a stream for logging. Although this works for the first 30 cases, on the 31st it crashes with a "Floating-point invalid operation".
The code is:
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";
When debugging, the value of swap_float the instance before the crash (on the last line, above) is 1711696.3 - other than this being much larger than most of the values up until this point, there is nothing particularly special about it.
I have also tried replacing message_stream with cerr, and got the same problem. I had hitherto believed cerr to be pretty much indestructable - how can a simple float destroy it?
Edit:
Thanks for the comments: I've added the declaration of mrSwap. mrSwap is approximately 200 long, so I'm a long way off the end. It is populated outside of my control, and individual entries may not be populated - but to the best of my understanding, this would just mean that swap_float would be set to a random float?
individual entries may not be populated - but to the best of my understanding, this would just mean that swap_float would be set to a random float?
Emphatically not. Certain bit patterns in an IEEE floating-point number indicate an invalid number -- for instance, the result of an overflowing arithmetic operation, or an invalid one (such as 0.0/0.0). The puzzling thing here is that the debugger apparently accepts the number as valid, while cout
doesn't.
Try getting the bit layout of swap_float
. On a 32-bit system:
int i = *(int*)&swap_float;
Then print i
in hexadecimal, and let us know what you see.
Updated to add: From Mike's comment, i=1238430338, which is 49D0F282 in hex. This is a valid floating-point number, equal to exactly 1711696.25. So I don't know what's going on, I'm afraid. The only thing I can suggest is that maybe the compiler is loading the invalid floating-point number directly from the mrSwap
array into the floating-point register bank, without going through swapFloat
. So the true value of swapFloat
is simply not available to the debugger. To check this, try
int j = *(int*)(mrSwap+30-1);
and tell us what you see.
Updated again to add: Another possibility is a delayed floating-point trap. The floating-point co-processor (built into the CPU these days) generates a floating-point interrupt because of some illegal operation, but the interrupt doesn't get noticed until the next floating-point operation is attempted. So this crash might be a result of the previous floating-point operation, which could be anywhere. Good luck with that...
这篇关于“浮点无效操作”当输入float到stringstream时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!