“浮点无效操作”当输入float到stringstream时 [英] "Floating-point invalid operation" when inputting float to a stringstream

查看:876
本文介绍了“浮点无效操作”当输入float到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

更新添加:从迈克的评论,i = 1238430338,这是十六进制49D0F282。这是一个有效的浮点数,等于1711696.25。所以我不知道发生了什么,恐怕。我唯一可以建议的是,也许编译器直接从 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆