0

Trying to transform a real_32 to real_64, I'm getting

real_32: 61.55
real_64: 61.54999923706055 

Am I wrong with the to_double function?

enter image description here

Pipo
  • 4,653
  • 38
  • 47

2 Answers2

1

This is expected. In the particular example, the binary representation of the decimal 61.55 with single and double precision respectively is:

REAL_32: 0    10000100 11101100011001100110011
REAL_64: 0 10000000100 1110110001100110011001100110011001100110011001100110

As you can see, the trailing pattern 0011 is recurrent and should go ad infinitum to give a precise value.

When REAL_32 is assigned to REAL_64, the trailing 0011s are not added automatically, but filled with zeroes instead:

REAL_32: 0    10000100 11101100011001100110011
REAL_64: 0 10000000100 1110110001100110011001100000000000000000000000000000

In decimal notation, this corresponds to 61.54999923706055. What is essential here, 61.54999923706055 and 61.55 have exactly the same binary representation when using single precision floating numbers. You can check it yourself with print ({REAL_32} 61.55 = {REAL_32} 61.54999923706055). In other words, the results you get are correct, and the two values are the same. The only difference is that when REAL_32 is printed, it is rounded to lower number of meaningful decimal digits.

This is the reason why accounting and bookkeeping software never uses floating-point numbers, only integer and decimal.

Alexander Kogtenkov
  • 5,770
  • 1
  • 27
  • 35
  • Thx for the explanation I learned a lot, is there a way to solve that with Eiffel? you mentioned integer and decimal... I still don't see how to solve this issue even if it is expected – Pipo Jan 26 '19 at 10:26
  • @Pipo If the original value always comes as a decimal number with known precision, either an integer with a scaling factor or a decimal number can represent it without loosing precision. This is known as [fixed-point arithmetic](https://en.wikipedia.org/wiki/Fixed-point_arithmetic). – Alexander Kogtenkov Jan 27 '19 at 07:45
  • thx which classes of eiffel should I use for decimal and floating-point? – Pipo Jan 27 '19 at 11:59
  • Giving me the explanation doesn't give me the solution how to transform a real_32 to a real_64 without having this issue... – Pipo Jan 27 '19 at 19:27
  • 1
    @Pipo There is no way to transform real_32 to real_64 without having the issue. If it's important to keep a specified precision, decimal arithmetic should be used instead. For example, the class `DECIMAL` from the library `decimal`. – Alexander Kogtenkov Jan 28 '19 at 07:19
0

As a workaround working for getting from JSON into typescript deserialization, the following worked:

 a_real_32.out.to_real_64
Pipo
  • 4,653
  • 38
  • 47
  • This may or may not work, depending on a particular input value. BTW, you are reading the number to make some operations on it, not just to output it immediately, right? Just try the "workaround" with some operation, e.g. `a_real_32.out.to_real_64 + 0.01` to see what's going on. – Alexander Kogtenkov Jan 28 '19 at 07:11