# Implement almost-equals for IEEE numbers

Isn't it annoying when you're working with floating point numbers and your code doesn't work because two numbers are not equal by the least significant bit? Now you can fix that!

Write some code that takes two floating point numbers in any IEEE 754 binary format and returns TRUE if:

• the two numbers are exactly equal
• for two positive numbers: adding the value of the least significant bit to the smaller number makes it exactly equal to the larger value
• for two negative numbers: subtracting the value of the least significant bit from the larger number makes it exactly equal to the smaller value

Return FALSE if:

• any other case

IEEE 754 allows both positive and negative zero. Treat all zeros as the sign of the other non-zero number. IEEE 754 defines 0 === -0. You can enter the numbers as text only if the binary representation in memory is accurate to the least significant bit.

### Test Data

The test data will vary slightly, depending on exactly which format your language uses. The table below shows the bit representation, followed by how to calculate the value, since most values will be impractical to directly input. A value such as -1.5b-3 means -1.5 x 2-3.

Your code must be able to handle every format your language supports:

• binary16 (Half precision)
• binary32 (Single precision)
• binary64 (Double precision)

If you are supporting any format other than binary64, expand or contract the bit patterns from the test data to their equivalents.

If your language doesn't natively support IEEE 754 at all, you may import an external library at no cost that fully implements at least one IEEE 754 binary format, but with no extra functions, i.e. you can't put your own function in the included library.

IEEE 754 binary64 (Double precision):

Zero and Subnormals:

0 00000000000 0000000000000000000000000000000000000000000000000000 (0)
0 00000000000 0000000000000000000000000000000000000000000000000001 (1b-1074)
TRUE

0 00000000000 0000000000000000000000000000000000000000000000000001 (1b-1074)
0 00000000000 0000000000000000000000000000000000000000000000000010 (1b-1073)
TRUE

0 00000000000 0000000000000000000000000000000000000000000000000000 (0)
0 00000000000 0000000000000000000000000000000000000000000000000010 (1b-1073)
FALSE

0 00000000000 0000000000000000000000000000000000000000000000000111 (1.75b-1072)
0 00000000000 0000000000000000000000000000000000000000000000001000 (1b-1071)
TRUE

0 00000000000 0000000000000000000000000000000000000000000000000000 (0)
1 00000000000 0000000000000000000000000000000000000000000000000001 (-1b-1074)
TRUE

1 00000000000 0000000000000000000000000000000000000000000000000001 (-1b-1074)
1 00000000000 0000000000000000000000000000000000000000000000000010 (-1b-1073)
TRUE

0 00000000000 0000000000000000000000000000000000000000000000000000 (0)
1 00000000000 0000000000000000000000000000000000000000000000000010 (-1b-1073)
FALSE

0 00000000000 0000000000000000000000000000000000000000000000000001 (1b-1074)
1 00000000000 0000000000000000000000000000000000000000000000000001 (-1b-1074)
FALSE


Normalised numbers:

0 01111111111 0000000000000000000000000000000000000000000000000000 (1)
0 01111111111 0000000000000000000000000000000000000000000000000010 (1 + 1b-51)
FALSE

0 01111111111 0000000000000000000000000000000000000000000000000000 (1)
0 01111111111 0000000000000000000000000000000000000000000000000001 (1 + 1b-52)
TRUE

0 01111111111 0000000000000000000000000000000000000000000000000000 (1)
0 01111111111 0000000000000000000000000000000000000000000000000000 (1)
TRUE

0 01111111111 0000000000000000000000000000000000000000000000000000 (1)
0 01111111110 1111111111111111111111111111111111111111111111111111 (1 - 1b-53)
TRUE

0 01111111111 0000000000000000000000000000000000000000000000000000 (1)
0 01111111110 1111111111111111111111111111111111111111111111111110 (1 - 1b-52)
FALSE

0 01111111111 0000000000000000000000000000000000000000000000000000 (1)
0 01111111110 0000000000000000000000000000000000000000000000000000 (0.5)
FALSE

0 10000010101 1111111111111111111111111111111111111111111111111110 (16777216 - 1b-28)
0 10000010110 0000000000000000000000000000000000000000000000000000 (16777216)
FALSE

0 10000010101 1111111111111111111111111111111111111111111111111111 (16777216 - 1b-29)
0 10000010110 0000000000000000000000000000000000000000000000000000 (16777216)
TRUE

0 10000010110 0000000000000000000000000000000000000000000000000000 (16777216)
0 10000010110 0000000000000000000000000000000000000000000000000000 (16777216)
TRUE

0 10000010110 0000000000000000000000000000000000000000000000000001 (16777216 + 1b-28)
0 10000010110 0000000000000000000000000000000000000000000000000000 (16777216)
TRUE

0 10000010110 0000000000000000000000000000000000000000000000000010 (16777216 + 1b-27)
0 10000010110 0000000000000000000000000000000000000000000000000000 (16777216)
FALSE

1 01111111101 0101010101010101010101010101010101010101010101010101 (-1 / 3)
1 01111111101 0101010101010101010101010101010101010101010101010111 (-1 / 3 - 1b-53)
FALSE

1 01111111101 0101010101010101010101010101010101010101010101010101 (-1 / 3)
1 01111111101 0101010101010101010101010101010101010101010101010110 (-1 / 3 - 1b-54)
TRUE

1 01111111101 0101010101010101010101010101010101010101010101010101 (-1 / 3)
1 01111111101 0101010101010101010101010101010101010101010101010101 (-1 / 3)
TRUE

1 01111111101 0101010101010101010101010101010101010101010101010101 (-1 / 3)
1 01111111101 0101010101010101010101010101010101010101010101010100 (-1 / 3 + 1b-54)
TRUE

1 01111111101 0101010101010101010101010101010101010101010101010101 (-1 / 3)
1 01111111101 0101010101010101010101010101010101010101010101010011 (-1 / 3 + 1b-53)
FALSE

1 11111111110 1111111111111111111111111111111111111111111111111111 (-1b1024 + 1b971)
1 11111111110 1111111111111111111111111111111111111111111111111111 (-1b1024 + 1b971)
TRUE

1 11111111110 1111111111111111111111111111111111111111111111111111 (-1b1024 + 1b971)
1 11111111110 1111111111111111111111111111111111111111111111111110 (-1b1024 + 1b970)
TRUE

1 11111111110 1111111111111111111111111111111111111111111111111111 (-1b1024 + 1b971)
1 11111111110 1111111111111111111111111111111111111111111111111101 (-1b1024 + 1.5b970)
FALSE


Infinity and Not A Number:

X 11111111111 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

INF
INF
TRUE

INF
Any other value
FALSE

-INF
-INF
TRUE

-INF
Any other value
FALSE

NAN
Any value, including NAN
FALSE


### Scoring

Number of bytes - (number of bytes needed for IEEE 754 library include, if an external library is used)

• > you can't put your own function in the included library. Isn't that already banned by standard loopholes? – lirtosiast Feb 6 '16 at 3:53
• @ThomasKwa I certainly hope so! I just wanted to make it explicit in case someone thought that was allowed, since I specifically said that adding an IEEE library would not count towards your score.. – CJ Dennis Feb 6 '16 at 4:01

# C++14 using IEEE754 platform, 17 + 49 = 66 bytes

Includes, 17 bytes:

#include <cmath>


Lambda expression, 49 bytes:

[](auto a,auto b){return b==std::nextafter(a,b);}

• Wow so the modern C++ has lambdas, nice! – busukxuan Feb 7 '16 at 3:02
• @busukxuan Even better, the auto means that this is a templated lambda :) – orlp Feb 7 '16 at 7:23