开发者

-NaN in printf in C

开发者 https://www.devze.com 2023-02-16 05:02 出处:网络
I am currently experiencing issues with a Raytracer \"Engine\" in some calculations. info->eyex = -1000.0;

I am currently experiencing issues with a Raytracer "Engine" in some calculations.

  info->eyex = -1000.0;
  info->eyey = 0.0;
  printf("%f et %f et %开发者_Python百科f et %f et %f\n", info->eyex, info->vx, info->eyey, info->vy, info->vz);

For example, in that piece of code, values seems good, but info->eyex gives me a -nan error.

It's weird, because I reset the value before.


My psychic sense tells me that eyex is declared as an int, not as a double as it should be. When you assign -1000.0 to it, it gets truncated to the integer -1000 (your compiler should give you a warning here), which is represented in binary as 0xFFFFFC18 using two's complement notation. Likewise, assuming that eye is also an integer, its value of 0 is represented in binary as 0x00000000.

When you pass eyex, eyey, and the other parameters to printf, they get pushed on the stack so that they lie in memory with increasing addresses. So immediately before the call instruction to call the subroutine, the stack frame looks something like this:

<top of stack>
0xFFFFFC18   ; eyex
(4-8 bytes)  ; vx
0x00000000   ; eyey
(4-8 bytes)  ; vy
(4-8 bytes)  ; vz

When printf sees the %f format specifier, that says "take 8 bytes off of the stack, interpret them as a double value, and print out that double value". So it sees the value 0xFFFFFC18xxxxxxxx, where the xxxxxxxxx is the value of info->vx. Regardless of that value, this is the IEEE 754 representation of NaN, or "not a number". It has the sign bit set, so some implementations may choose to interpret this as "negative NaN", though this has the same semantics as regular NaN.

Your compiler should also be warning you here that you're passing the wrong types of arguments to printf—it's expecting a double but you're not passing it that. GCC enables these warnings with -Wall, which I highly recommend enabling.

So, the solution is to declare eyex to be of type double (and presumably the other variables to also be double, if they're not already). Alternatively, if you don't control the definition of eyex et al (say, because they're part of a structure for a third-party library), then what you should instead be doing is printing them out with the %d modifier to print them as integers, not with %f, and you should also assign them integer values such as -1000 and 0, not floating-point values such as -1000.0 and 0.0.


Just to confirm this. I don't know exactly what triggers that behavior, though. printf is optimized at compile time, and the format string analyzed. Probably it's (wrongly) assuming something about your variable. Even though %f should work for doubles and floats, it seems it doesn't always (at least with gcc 4.4.5, which is the one I'm using)

Try assigning the value to another variable and then passing that to printf. Although ugly, that solved the problem for me.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号