Page 3 of 3

Re: Rounding Bug

Posted: 09 Mar 2023, 08:50
by off
Is this bug still appear when we just add 0 at the end of decimal? Like 1.0350 for example..

Re: Rounding Bug

Posted: 14 Feb 2024, 10:07
by hitman
Version 2.0.11

Code: Select all

n := 2.515
MsgBox  Round(n,2) ; ->2.52 Correct

n := 3.515
MsgBox  Round(n,2) ; ->3.52 Correct

n := 4.515
MsgBox  Round(n,2) ; ->4.51  It's not correct!!!

n := 5.515
MsgBox  Round(n,2)  ; ->5.52 Correct
[Mod edit: Added [code][/code] tags. Please use them yourself when posting code!]

Re: Rounding Bug

Posted: 14 Feb 2024, 12:29
by geek
Nothing wrong here, 4.515 in decimal cannot be perfectly represented by the IEEE754 format used to encode floats in binary for computers to process. It's like how 1/3 in decimal can't be perfectly encoded, but instead with limited resources you might write it as as 3.333332 The closest value in binary is about 4.5149999999999997, which rounds down to 4.51. You can see for yourself, if you do MsgBox 4.515 it shows that closest supported value.

Re: Rounding Bug

Posted: 14 Feb 2024, 13:50
by joefiesta
Can anyone say why this argument is not settled by simply adding remarks as to the this behavior to the round() function's documentation?

should it be necessary that someone suggests to do what is patently obvious?

Re: Rounding Bug

Posted: 14 Feb 2024, 20:32
by hitman

Code: Select all

SRound(Num, N := "")
{
   if (N = "") || (N = 0)
      return Round(Num)
   else if (N < 0)
      return Round(Num, N)
   else ; N > 0
   {
      return Round(Round(Num * (10**(N+1)), -1) / (10**(N+1)),N)
   }
}

Re: Rounding Bug

Posted: 15 Feb 2024, 10:32
by lmstearn
Nice example of floating point operations.
All floating point numbers with a non-zero mantissa do not have exact representations, e.g, the following are printed according to IEEE 754 and:

Code: Select all

Format("{1:.15f}", .n)
n := 0.1 ; 0.10000000000000001
n := 0.3 ; 0.29999999999999999
n := 0.4 ; 0.40000000000000002
n := 0.5 ; 0.5
n := 0.6 ; 0.59999999999999998
n := 0.7 ; 0.69999999999999996
n := 0.8 ; 0.80000000000000004
n := 0.9 ; 0.90000000000000002

n := 0.01 ; 0.01
n := 0.02 ; 0.02
n := 0.03 ; 0.029999999999999999
n := 0.04 ; 0.040000000000000001
n := 0.05 ; 0.050000000000000003
n := 0.06 ; 0.059999999999999998
n := 0.07 ; 0.070000000000000007
n := 0.08 ; 0.080000000000000002
n := 0.09 ; 0.089999999999999997


n := 0.001 ; 0.001
n := 1.001 ; 1.0009999999999999
n := 2.001 ; 2.0009999999999999
n := 3.001 ; 3.0009999999999999
n := 4.001 ; 4.0010000000000003
n := 5.001 ; 5.0010000000000003
n := 6.001 ; 6.0010000000000003
n := 7.001 ; 7.0010000000000003
n := 8.001 ; 8.0009999999999994
n := 9.001 ; 9.0009999999999994
n := 10.001 ; 10.000999999999999
n := 11.001 ; 11.000999999999999
n := 12.001 ; 12.000999999999999
n := 13.001 ; 13.000999999999999
n := 14.001 ; 14.000999999999999
n := 15.001 ; 15.000999999999999
n := 16.001 ; 16.001000000000001
n := 17.001 ; 17.001000000000001
n := 18.001 ; 18.001000000000001
n := 19.001 ; 19.001000000000001
n := 20.001 ; 20.001000000000001
n := 21.001 ; 21.001000000000001
n := 22.001 ; 22.001000000000001
n := 23.001 ; 23.001000000000001
n := 24.001 ; 24.001000000000001
n := 25.001 ; 25.001000000000001
n := 26.001 ; 26.001000000000001
n := 27.001 ; 27.001000000000001
n := 28.001 ; 28.001000000000001
n := 29.001 ; 29.001000000000001
n := 30.001 ; 30.001000000000001
n := 31.001 ; 31.001000000000001
n := 32.001 ; 32.000999999999998
;...
n := 63.001 ; 63.000999999999998
n := 64.001 ; 64.001000000000005
n := 65.001 ; 65.001000000000005
n := 65.001 ; 65.0010000000000048
The pattern is based on the binary bit length of the exponent. The ones that appear accurate can be checked again with:

Code: Select all

Format("{1:.23f}", n)
Nice article at CodeProject explaining more.