Strange error making some calculations

Strange error making some calculations

Postby Massimo Linossi » Thu Mar 22, 2018 9:27 am

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 view

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 view

     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
Massimo Linossi
 
Posts: 495
Joined: Mon Oct 17, 2005 10:38 am
Location: Italy

Re: Strange error making some calculations

Postby nageswaragunupudi » Thu Mar 22, 2018 9:54 am

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

? tot < 0.5 // .T.

So,
Code: Select all  Expand view
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
nageswaragunupudi
 
Posts: 10248
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Strange error making some calculations

Postby Enrico Maria Giordano » Thu Mar 22, 2018 10:00 am

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

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


EMG
User avatar
Enrico Maria Giordano
 
Posts: 8315
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Re: Strange error making some calculations

Postby Massimo Linossi » Thu Mar 22, 2018 10:04 am

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
Massimo Linossi
 
Posts: 495
Joined: Mon Oct 17, 2005 10:38 am
Location: Italy

Re: Strange error making some calculations

Postby Enrico Maria Giordano » Thu Mar 22, 2018 10:12 am

Try adding

Code: Select all  Expand view
SET FIXED ON
SET DECIMALS TO 15


and you'll see the same result.

EMG
User avatar
Enrico Maria Giordano
 
Posts: 8315
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Re: Strange error making some calculations

Postby Massimo Linossi » Thu Mar 22, 2018 10:18 am

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
Massimo Linossi
 
Posts: 495
Joined: Mon Oct 17, 2005 10:38 am
Location: Italy

Re: Strange error making some calculations

Postby Enrico Maria Giordano » Thu Mar 22, 2018 10:29 am

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
Enrico Maria Giordano
 
Posts: 8315
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Re: Strange error making some calculations

Postby Massimo Linossi » Thu Mar 22, 2018 10:42 am

Thanks Enrico for your explanation and for your time.
Massimo
User avatar
Massimo Linossi
 
Posts: 495
Joined: Mon Oct 17, 2005 10:38 am
Location: Italy

Re: Strange error making some calculations

Postby Enrico Maria Giordano » Thu Mar 22, 2018 11:07 am

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
Enrico Maria Giordano
 
Posts: 8315
Joined: Thu Oct 06, 2005 8:17 pm
Location: Roma - Italia

Re: Strange error making some calculations

Postby Massimo Linossi » Thu Mar 22, 2018 11:15 am

Thanks a lot.
Massimo
User avatar
Massimo Linossi
 
Posts: 495
Joined: Mon Oct 17, 2005 10:38 am
Location: Italy


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 93 guests