Strange error making some calculations

Post Reply
User avatar
Massimo Linossi
Posts: 508
Joined: Mon Oct 17, 2005 10:38 am
Location: Italy

Strange error making some calculations

Post by Massimo Linossi »

Hi to all.
I had a strange problem making some calculations.
If I use some variables ad I sum them, the result is correct, but multiplying it the result is wrong.
Making the same multiply with the same total the result is correct. 

Code: Select all | Expand


Function calc
local a1:=0 , a2:=0 , a3:=0 , a4:=0 , tot:=0 , iva:=0

a1:=11.57
a2:=4.20
a3:=0.56
a4:=-16.28

tot:=a1 + a2 + a3 + a4
iva:=Round(tot*10/100,2)
? tot                   // 0.05 correct
? iva                   // 0.00 wrong

tot:=0.05
iva:=Round(tot*10/100,2)
? tot                   // 0.05 correct
? iva                   // 0.01 correct
return nil
 


I made the same program in COBOL and the result is correct

Code: Select all | Expand


     IDENTIFICATION DIVISION.
          PROGRAM-ID.              CALCOLA.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SOURCE-COMPUTER.            IBM-AT.
       OBJECT-COMPUTER.            IBM-AT.
       SPECIAL-NAMES.    DECIMAL-POINT IS COMMA.

       INPUT-OUTPUT SECTION.
       FILE-CONTROL.

            SELECT OPTIONAL PILOTA
            ASSIGN TO RANDOM "PILOTA.DAT"
            ORGANIZATION IS RELATIVE
            ACCESS MODE IS RANDOM
            RELATIVE KEY IS NUMREPI.

       DATA DIVISION.
       FILE SECTION.

       FD PILOTA
            BLOCK CONTAINS 1 RECORDS
            LABEL RECORD IS STANDARD
            DATA RECORD IS REC-PIL.
       01  REC-PIL.
            02 PIL-NUMBOLLE   PIC 9(5).
            02 PIL-NUMFATT    PIC 9(5).
            02 PIL-CLIENTI    PIC 9(6).
            02 PIL-FORNIT     PIC 9(6).
            02 PIL-CARICHI    PIC 9(6).
            02 PIL-SCARICHI   PIC 9(6).
            02 PIL-SCADENZE   PIC 9(5).
            02 PIL-FILLER     PIC X.

       WORKING-STORAGE SECTION.
       77 NUMREPI                 PIC 9 VALUE 1.
       77 RISPOSTA                PIC X.
       77 CAMPO-DISPLAY           PIC 99,99.
       01 CAMPI-CALCOLO.
          02 VALORE1                       PIC S99V99.
          02 VALORE2                       PIC S99V99.
          02 VALORE3                       PIC S99V99.
          02 VALORE4                       PIC S99V99.
          02 VALORE5                       PIC S99V99.
          02 TOTALE1                       PIC S99V99.
          02 ALIQUOTA                      PIC S99V99.
          02 IVA                           PIC S99V99.

        PROCEDURE DIVISION.
        PARTENZA.
            INITIALIZE CAMPI-CALCOLO.
            MOVE 11,57  TO VALORE1.
            MOVE 4,20   TO VALORE2.
            MOVE 0,56   TO VALORE3.
            MOVE -16,28 TO VALORE4.

            ADD VALORE1 TO TOTALE1.
            ADD VALORE2 TO TOTALE1.
            ADD VALORE3 TO TOTALE1.
            ADD VALORE4 TO TOTALE1.

            MOVE 10 TO ALIQUOTA.
            COMPUTE IVA ROUNDED = TOTALE1 * ALIQUOTA / 100.

        FINE-LAVORO.
            MOVE TOTALE1 TO CAMPO-DISPLAY
            DISPLAY CAMPO-DISPLAY.
            MOVE IVA TO CAMPO-DISPLAY
            DISPLAY CAMPO-DISPLAY.
            ACCEPT RISPOSTA.
        STOP-RUN.
            STOP RUN.
 


TOTALE1 is equal to 0.05 and IVA is 0.01
User avatar
nageswaragunupudi
Posts: 10721
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Been thanked: 8 times
Contact:

Re: Strange error making some calculations

Post by nageswaragunupudi »

Clipper/Harbour uses floating point math which is not always precise when converted to decimals.

? tot < 0.5 // .T.

So,

Code: Select all | Expand

tot:= round( a1 + a2 + a3 + a4, 2 )
iva:=Round( tot*10/100,2)
? tot                   // 0.05 correct
? iva                   // 0.01 right
 

Having known the limitations and side-effects of floating point math, it is a good idea to use round() after long summations.

Cobol uses BCD math.
Regards

G. N. Rao.
Hyderabad, India
User avatar
Enrico Maria Giordano
Posts: 8753
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Has thanked: 1 time
Been thanked: 4 times
Contact:

Re: Strange error making some calculations

Post by Enrico Maria Giordano »

It's the usual floating-point behavior. To fix it you have to round tot too:

Code: Select all | Expand

tot:=a1 + a2 + a3 + a4
tot = Round(tot,2) //add this
iva:=Round(tot*10/100,2)


EMG
User avatar
Massimo Linossi
Posts: 508
Joined: Mon Oct 17, 2005 10:38 am
Location: Italy

Re: Strange error making some calculations

Post by Massimo Linossi »

Hi Nages.
Thanks for your explanation. But what I don't understand is that the calc is correct, the sum isn't wrong.
With the same datas the iva calc is wrong, but the starting value is the same. the msginfo of tot is equal.
Is you make the same calc with Excel, using 2 decimals, is still wrong.
with Numbers on iMac I have this terrible result :

Image
User avatar
Enrico Maria Giordano
Posts: 8753
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Has thanked: 1 time
Been thanked: 4 times
Contact:

Re: Strange error making some calculations

Post by Enrico Maria Giordano »

Try adding

Code: Select all | Expand

SET FIXED ON
SET DECIMALS TO 15


and you'll see the same result.

EMG
User avatar
Massimo Linossi
Posts: 508
Joined: Mon Oct 17, 2005 10:38 am
Location: Italy

Re: Strange error making some calculations

Post by Massimo Linossi »

Ok, you're right.
But I'm using some constants with 2 fixed decimals, not floating numbers.
Making the calc with a scientific pocket calculator, the result is correct.
I've tried with FORTRAN too, with 2 decimals and floating point variables and the result is correct, without using rounding functions.
User avatar
Enrico Maria Giordano
Posts: 8753
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Has thanked: 1 time
Been thanked: 4 times
Contact:

Re: Strange error making some calculations

Post by Enrico Maria Giordano »

Massimo,

you have to understand how floating-point work. Not doing so you'll find a lot of strange behaviour, in any programming language.

EMG
User avatar
Massimo Linossi
Posts: 508
Joined: Mon Oct 17, 2005 10:38 am
Location: Italy

Re: Strange error making some calculations

Post by Massimo Linossi »

Thanks Enrico for your explanation and for your time.
Massimo
User avatar
Enrico Maria Giordano
Posts: 8753
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia
Has thanked: 1 time
Been thanked: 4 times
Contact:

Re: Strange error making some calculations

Post by Enrico Maria Giordano »

As an example: take 1/10. What result do you expect from this? 0.1 for sure. Well, using floating-point you could get 0.100000000001 or 0.099999999999 or similar results instead. If you hide the decimals you will se 0.1 or 0.0 according to the actual result. If you round the result you will get the correct one.

But why floating-point acts in so strange way? Because a decimal value with a finite number of decimals when converted to binary could have an infinite number of decimals.

EMG
User avatar
Massimo Linossi
Posts: 508
Joined: Mon Oct 17, 2005 10:38 am
Location: Italy

Re: Strange error making some calculations

Post by Massimo Linossi »

Thanks a lot.
Massimo
Post Reply