0
$\begingroup$

In simple precision format, the largest possible positive number is

$A = 0 ~~~ 11111110 ~~~ 111\ldots 111$

Its predecessor is

$B = 0 ~~~ 11111110 ~~~ 111 \ldots 110$

But what is the absolute difference (in decimal) between these?

Appealing to scientific notation,

$A = 0.(2^{22}+2^{23}+\ldots + 2 + 1) \times 2^{2^{7}+2^{6} + 2 + 1 - 127}$

and

$B = 0.(2^{22}+2^{23}+\ldots + 2 + 0) \times 2^{2^{7}+2^{6} + 2 + 1 - 127}$

So they have only a difference of one point in the last decimal digit. The exponent tells us there are $2^{7} + \ldots + 2 + 1 - 127$ such decimal points. Let $e$ denote that quantity. Is it correct to say the difference is

$$0.\overbrace{000\ldots 000}^{e \text{ times}}1$$

or am I missing something?

$\endgroup$
1
  • $\begingroup$ In the example, what is the numerical value of $e$? I am having trouble following the reasoning here, and it seems to me that the implicit leading bit (the integer bit) of the significand has been omitted. In IEEE-754 binary arithmetic, other than for subnormals, all significands are of the form $1.x \ldots x$, with $x \in {0, 1}$. $\endgroup$
    – njuffa
    Nov 16, 2023 at 0:27

1 Answer 1

1
$\begingroup$

The IEEE-754 binary32 format comprises a sign bit, eight exponent bits, and twenty-three stored significand bits. The stored exponent is biased by 127. For normal operands, the significand actually comprises twenty-four bits that encode values in $[1, 2)$. Since this means that the most significant bit of the significand is always 1, it is not stored. If we denote the largest finite binary32 operand by $a$ and its immediate predecessor by $b$, their binary encodings are

       s exponent significand
   a = 0_11111110_11111111111111111111111  largest finite binary32
   b = 0_11111110_11111111111111111111110  its immediate predecessor

The most significant bit of the stored significand has numerical weight $2^{-1}$, while the least significant bit of the stored significand has numerical weight $2^{-23}$. If we take into account exponent bias, the numerical values of the two operands are

                   2⁰ 2⁻¹                   2⁻²³
                    ↓ ↓                     ↓ 
   a = 2⁽²⁵⁴⁻¹²⁷⁾ * 1.11111111111111111111111
   b = 2⁽²⁵⁴⁻¹²⁷⁾ * 1.11111111111111111111110

The difference $a- b$ is therefore $2^{(254-127)} \cdot 2^{-23} = 2^{104} \approx 2.02824096 \cdot 10^{31}$. We could also confirm this experimentally, for example with the following ISO-C99 program:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int main (void)
{
    uint32_t ai = 0x7f7fffff; // largest finite binary32
    uint32_t bi = 0x7f7ffffe; // its immediate predecessor
    float a, b, diff;
    memcpy (&a, &ai, sizeof a);
    memcpy (&b, &bi, sizeof b);
    diff = a - b;
    printf ("diff = %15.8e  %15.6a  log2(diff)=%f\n", diff, diff, log2f (diff));
    return EXIT_SUCCESS;
}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.