Explanation of Rounding of two Ieee754 numbers

37 Views Asked by At

Recently I have been creating a Standard Library for my custom language. The library contains some soft floating point functionality because my target processor does not have an FPU.I don't support double precision floating point numbers I only support single precision because my target architecture is 32 bits.

Currently I have all the floating point functions defined however I haven't implemented any sort of rounding.

My Compiler is written in Java and I currently have some test cases that runs an Interpreter over the source program and runs my custom IR in a virtual Machine and then compares the result to make sure it matches.

The Ir Virtual machine makes use of my soft floating point functionality while the Interpreter does everything with Java operations. The reason being is the interpreted source is not linked but the Ir module is statically linked to the standard library and contains the soft floating point operations. The Interpreter has support for the standard library calls but the functionality is literally built into the interpreter it is not extracted from a library file of my source language.

Because of the above the Interpreter is giving me a different result then my linked Ir Module.

My Interpreters output is the following

H is 1
I is 3.141593
H is 1
I is 3.141593
6

My ran Ir Module output is the following

H is 1
I is 3.1415925
H is 1
I is 3.1415925
H is 1
I is 3.1415925
H is 1
I is 3.1415925
3.8146973E-6

For now you can ignore the bottom number being different. As well as there being more lines in the ir module. What I would like to know is why in the interpreter after dividing 355 / 113 and getting 3.141593 instead of 3.1415925.

Well to be more specific I know the why it is because I haven't implemented the Rounding functionality.

ICode Vm result    | 3.1415925 | 01000000010010010000111111011010
Interpreter result | 3.141593  | 01000000010010010000111111011100

so my question is why is it rounded in this way. Like why is it the second bit and not the first that gets rounded or in this case would stay the same since they are both zero.

I looked for several solutions online and I came up with something about a sticky bit and a bunch of other weird stuff that I didn't really understand. Just figured someone might know a bit more then me about ieee754 standard on here.

1

There are 1 best solutions below

3
Eric Postpischil On

When 355 is divided by 113, the quotient is +21•1.1001 0010 0001 1111 1011 0111 1000 0001 0010 0001 1111…2.

The significand of the IEEE-754 binary32 format has 24 bits, so we need to round that significand at the point marked with “^”: 1.1001 0010 0001 1111 1011 011^1 1000 0001 0010 0001 1111…2.

IEEE-754 does not dictate what rounding method must be used. It offers a choice. You can round down, toward −∞, which would produce 1.1001 0010 0001 1111 1011 0112.

You can round upward, toward +∞, which would produce 1.1001 0010 0001 1111 1011 1002. Observe that this is the next representable value after the value above. We just incremented the significand to the next step.

You can round toward zero, which, for positive numbers, produces the same thing as rounding toward −∞.

The most common method, and the default, is to round to the nearest representable value, and, if there is a tie, to round to the choice with the even low digit. (There is also a special case for decimal formats, not relevant here.)

In 1.1001 0010 0001 1111 1011 011^1 1000 0001 0010 0001 1111…2, rounding down makes a difference of 1 1000…2 at the rounding point marked with “^”. Rounding up makes a difference of 0 0111… at the rounding point. The greater number is nearer to the exact result. So rounding to nearest produces the greater number, +21•1.1001 0010 0001 1111 1011 1002. That is 3.14159297943115234375.