Question about NaN?

In relation to this thread - http://arduino.cc/forum/index.php/topic,89713.0.html which was recently solved by figuring out that a variable had become Not a Number.

I have a question about how that gets handled by the processor.

Let's say I have an unsigned char. It can have values from 0 (b00000000) to 255 (b11111111) and that covers every possible permutation of 8 bits in a byte. So what happens when it becomes NaN. Like if I try to divide by zero. What would then be actually stored at that memory location and how would the processor identify that as NaN at a later time when it comes to retrieve that variable? Since I'm using all of the bits to represent numbers, where does the information that it is not a number come into play?

Not a number is not a storage state, it is a state that results from an operation that dosn't make sense. Like dividing by zero will produce a value in the registers but it can not be treated as a number.

Keywords are "ieee" and "754".

http://en.wikipedia.org/wiki/IEEE_754-2008 http://en.wikipedia.org/wiki/Single_precision_floating-point_format http://en.wikipedia.org/wiki/Single_precision_floating-point_format#Exponent_encoding

OK. Yes I know it's not a storage state. I guess I worded my question poorly.

The real question was how does the processor keep up with that little tid-bit of information the next time the code tries to use that variable. If I call isnan() on that variable, where does it look to find out. And what gets stuck into the memory location of that variable (if that is even a defined behavior).

If I understand correctly what I just read (Thanks Coding Badly) it's in a flag in the status register somewhere. Is this right?

Only on processors that have a floating-point unit (i.e. [u]not[/u] any current Arduino processors). The third link has the details... Exponent = FFH; Significand non-zero. The second link has the in-memory data format. Bits 23 through 30 are all ones and bits 0 through 22 are non-zero. I assume bit 31 is "don't care".

The source code for isnan (and all the other float-point things) is available... http://www.nongnu.org/avr-libc/ http://download.savannah.gnu.org/releases/avr-libc/

Delta_G: Let's say I have an unsigned char. It can have values from 0 (b00000000) to 255 (b11111111) and that covers every possible permutation of 8 bits in a byte. So what happens when it becomes NaN.

That won't happen to unsigned char. Only floating point numbers (type float/double) have a bit pattern that represents NaN. It's just a certain set of bits (high-order two bits from memory) that get set for divide by zero, square root of -1 that sort of thing. So that NaN state gets copied around with the number. It's not a processor flag. I'm guessing that attempts to add/subtract/compare NaN numbers immediately fail. So if i and j are NaN they are neither greater than, less than, nor equal to each other.

Aha! I think I see the answer to my confusion. NaN isn’t something that is ever going to happen to an integer data type? It’s just a float thing? And there is more than just numerical information in the float type.

And Nick answered that while I was typing. Thanks!!! :slight_smile:

Is the behavior of dividing an int by zero defined?

Is the behavior of dividing an int by zero defined?

No, I'm pretty sure the c/c++ standard explicitly states this behaviour as undefined, i.e. processor dependant results.

I guess the pertinent question then is will a divide by 0 result in a stop code and exit from function "Main"?

will a divide by 0 result in a stop code and exit from function “Main”?

No.

Some processors have traps (interrupt vectors) that are triggered by a divide by zero. I know the 68000 had one but there is nothing comparable in the arduino’s processor.

Note that the AVR processors (at least those currently used in Arduinos) don't even have a DIVIDE instruction; it has to be done in software. The software could theoretically use one of the other unused/unusable interrupt vectors to do a "Divide by Zero" exception (or it could do anything else), but it doesn't.

ajofscott: I guess the pertinent question then is will a divide by 0 result in a stop code and exit from function "Main"?

I'm not sure where it would go if it exited from "main". It has to do something.

Conceivably the writers of the library could make it go into a loop if you try to divide by zero. Not sure if that would be helpful.