Search code examples
ieee-754divide-by-zero

IEEE 754, division by zero


I know in standard IEEE 754 division by zero is allowed. I want to know how it's represented in binary.

For example, 0.25 in decimal is 0 01111101 00000000000000000000000 in binary. What about 5.0/0.0 or 0.0/0.0 do they have represenation in binary, and are they same? Thanks.


Solution

  • When you divide a finite number by zero you'll get an infinity with the sign of the number you tried to divide. So 5.0/0.0 is +inf but 0.0/0.0 returns something called a QNaN indefinite.

    Let’s say we are dividing negative one by zero. Because this results in a pre-computed exception I think the key to understanding what happens is in the “response” verbiage Intel uses in section 4.9.1.2

    The masked response for the divide-by-zero exception is to set the ZE flag and return an infinity signed with the exclusive OR of the sign of the operands.

    I hope I’m reading this right. Since the Zero mask bit (found in the control word of the x87 FPU) is a 1, the pre-computed exception flag becomes set once the fpu detects the zero in the operand used for division. Now the processor knows to do something like this:

        1 sign of operand 1, our -1.0
    xor 0 sign of operand 2, the zero 
    ----------
        1 response
    

    Now with that response bit I know whether I have a positive or negative infinity

    -inf 1 11111111 00000000000000000000000
    -----+-+------+-+---------------------+
         | |      | |                     |
         | +------+ +---------------------+
         |    |               |
         |    v               v
         | exponent        fraction
         |
         v
         sign
    

    If I had a positive 1.0 instead and divided by zero:

        0 sign of operand 1
    xor 0 sign of operand 2
    -----------
        0 
    

    Now I have inf 0 11111111 00000000000000000000000

    As long as the numerator is positive and you're dividing by zero you'll get the same positive infinity. This is what I imagine happening when I run something like this:

    int main() {
        SetExceptionMask(exAllArithmeticExceptions);    
        float a = -1;
        float b = a / 0.0f;
        printf("%f\n", b);
    }
    

    The result is -inf which looks like this 1 11111111 00000000000000000000000

    QNaNs ("quiet not a number") are especially helpful for debugging and are generated through a few different ways but 0.0/0.0 will return something that looks like this:

    qnan 0 11111111 10000000000000000000000
    -----+-+------+-+---------------------+
                    |                     |
                    +---------------------+
                             |
                             v
                          fraction
    

    Now software can manipulate the bits in the fraction of a QNaN for any purpose, usually this seems done for diagnostic purposes. To learn more I recommend watching parts 31(https://youtu.be/SsDoUirLkbY), and 33(https://youtu.be/3ZxXSUPSFaQ) of this Intel Manual reading.