IEEE 754, division by zero

给你一囗甜甜゛ 提交于 2020-01-04 05:12:07

问题


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.


回答1:


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.




回答2:


Mark has corrected me that division by zero results in positive or negative infinity in IEEE 754-2208.

In the wikipedia article on the subject, we find the following:

sign = 0 for positive infinity, 1 for negative infinity.

biased exponent = all 1 bits.

fraction = all 0 bits.

Source: IEEE 754 Wikipedia article

I was wrong in thinking it would result in a NaN, upon which I elaborated below.

+Infinity:

0 11111111 00000000000000000000000

-Infinity:

1 11111111 00000000000000000000000

INCORRECT ORIGINAL RESPONSE BELOW

May still be of tangential interest, so leaving it in.


This results in, from my understanding, a NaN, pr **not a number*.

The wikipedia page on Nan has an encoding section from which the following quote arrives.

In IEEE 754 standard-conforming floating-point storage formats, NaNs are identified by specific, pre-defined bit patterns unique to NaNs. The sign bit does not matter. Binary format NaNs are represented with the exponential field filled with ones (like infinity values), and some non-zero number in the significand (to make them distinct from infinity values). The original IEEE 754 standard from 1985 (IEEE 754-1985) only described binary floating-point formats, and did not specify how the signaled/quiet state was to be tagged. In practice, the most significant bit of the significand determined whether a NaN is signalling or quiet. Two different implementations, with reversed meanings, resulted.

Source: NaN Encoding (Wikipedia)

The article also goes on to note that in 2008, the IEEE 754-2008 revision adds a suggested method for indicating if the NaN should be quiet or verbose.

NaN is identified by having the top five bits of the combination field after the sign bit set to ones. The sixth bit of the field is the 'is_quiet' flag. The standard follows the interpretation as an 'is_signaling' flag. I.e. the signaled/quiet bit is zero if the NaN is quiet, and non-zero if the N is identified by having the aN is signaling.

Basically, as before, the exponent is all ones, and the last bit indicates whether it is quiet or not.

My interpretation is that a NaN could be represented in a number of ways, including as follows:

0 11111111 00000000000000000000010


来源:https://stackoverflow.com/questions/33678698/ieee-754-division-by-zero

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!