[Gambas-user] Best ways to format float values

Tobias Boege taboege at ...626...
Thu Jul 13 20:00:19 CEST 2017


On Thu, 13 Jul 2017, Gianluigi wrote:
> I would not be misunderstood.
> I had understood that Alex wanted a forced increase "Round".
> 
> To recap:
> 
>   Dim n As Float = 26.6601666666666
>   Dim b As Byte
> 
>   Print Int(n * 100) / 100              ' Normal truncate, as already
> mentioned by other
>   Print Round(n, -2)                    ' Normal round, as already
> mentioned by other
>   If Len(CStr(Frac(n))) > 4 Then
>     b = Val(Mid(CStr(Frac(n)), 5, 1))
>     If b >= 5 Then
>       Print Round(n, -2)
>     Else
>       Print Round(n + 0.01, -2)         ' Forced increase round, as
> proposed by me
>     Endif
>   Endif
> 

I would avoid arithmetic operations involving even more floats, such as you
proposed. Consider this:

  $ gbx3 -e 'Round(0.80999999950+0.1,-9)'
  0.909999999
  $ gbx3 -e 'Round(0.80999999951+0.1,-9)'
  0.91

I only changed the very last digit (of order 10^-11) from 0 to 1 which
shouldn't influence the rouding to 9 decimals at all -- but it does!

The problem here is, famously, that the decimal 0.1 has no finite binary
representation, so *storing* the value that is represented in decimal by
the string "0.1" in a binary float already gives you an unavoidable error.
Whenever you use 0.1 in your program, this error propagates. Specifically,
the error when storing 0.1 in a Single is about 1.49*10^-9, which is how
I arrived at that example above.

Of course, the same applies to the 0.01 you use above. You can think
by yourself about a similar example where float addition with 0.01 makes
the result of a later rounding unreliable.

The other method

  Floor(n*100)/100  ' round down to two decimals
  Ceil(n*100)/100   ' round up to two decimals

is reliable, since the *integer* 100 can be stored without error in a
float and IEEE754 requires the outcome of float arithmetic to be the
same as if the operation was performed exactly and then rounded to the
limited precision of the float datatype [1].

Regards,
Tobi

[1] http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html#865

-- 
"There's an old saying: Don't change anything... ever!" -- Mr. Monk




More information about the User mailing list