comp.lang.ada
 help / color / mirror / Atom feed
From: Al Christians <achrist@easystreet.com>
Subject: Re: fixed type (delta) in ada
Date: 1999/11/26
Date: 1999-11-26T00:00:00+00:00	[thread overview]
Message-ID: <383F808E.66464E08@easystreet.com> (raw)
In-Reply-To: 383f6dbb.22609744@news.tstonramp.com

I ran your test with GNAT 3.12p under Windows NT on Pentium Pro.  I 
get the answer = 68.55.  Equally no good or even a little worse.

Your fixed point numbers are all binary fixed point.  This is all 
according to the book; don't worry.

Delta = 0.01 works out to use binary fixed point with 7 bits to the 
right of the binary point, ie numbers are represented as some number 
of 128ths; 1/128 is less than 0.01, so these are good to 2 decimal 
digits to the right of the decimal point.  Unfortunately, it looks 
like your 0.20 value gets represented by GNAT as 25/128, even though  
26/128 is a little closer, neither is very close.  Whatever Ada you 
were using is using 26/128 and is a little more accurate than GNAT 
3.12p, but there's a way around this either way (below).

If I do this:
 
a:     constant := 351.0;
b:     constant := 1.0/5.0;
d:     constant := a * b;
c:     constant money := d;

Then c comes out with the right value of 70.2.  a, b, and
d, are each of type universal_real, with beaucoups of significant
digits, and therefore c comes out ok.


But if I do this:
 
a:     constant := 351.0;
b:     constant := 1.0/5.0;
c:     constant money := a * b;

Then c still comes out 68.55.  Looks like the a and b get converted
to the money type before they get multiplied.  Ouch.

But to make money a decimal fixed point type type, do this:

-----------------------------------------------------------

with Ada.Text_IO;

procedure Money_Test is

type money is delta 0.01 digits 10 range 0.0..10_000_000.00;

a:     money;
b:     money;
c:     money;

package money_io is new ada.text_io.decimal_io(money);


begin
a     := 351.0;
b     := 0.20;
c     := (a * b);   
money_io.put(c);  -- Prints 70.2 
end Money_Test;

--------------------------------------------------------------

This gives the right answer with no error.  The range constraint
on the money type is optional; the digits + delta part combined
make the numbers act like decimal numbers.



Al


Nap wrote:
> 
> does anyone know why mutiplication between fixed type in ada produce a
> big round off error?
> 
> type money is delta 0.01 range 0.0..100_000_000.00;
> a, b, c : money;
> 
> package money_io is new ada.text_io.fixed_io(money);
> 
> a := 351.00;
> b := 0.20;
> c := a * b;
> 
> money_io.put(c);
> 
> -- the output should be 70.2 but it prints 71.3 instead.
> -- this is so frustrating. typecasting (back to float) doesn't help
> either.
> 
> Thanks,
> Nap




  reply	other threads:[~1999-11-26  0:00 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-11-27  0:00 fixed type (delta) in ada Nap
1999-11-26  0:00 ` Al Christians [this message]
1999-11-27  0:00   ` fixed type (delta) in ada and GNAT bug David C. Hoos, Sr.
1999-11-28  0:00 ` fixed type (delta) in ada Nick Roberts
1999-11-30  0:00   ` Simon Wright
1999-11-28  0:00 ` Robert Dewar
1999-11-27  0:00   ` Al Christians
1999-11-28  0:00     ` Florian Weimer
1999-11-28  0:00       ` Al Christians
1999-11-29  0:00         ` Preben Randhol
1999-11-29  0:00           ` Al Christians
1999-11-29  0:00             ` Preben Randhol
1999-11-28  0:00     ` Preben Randhol
1999-11-29  0:00     ` Robert Dewar
1999-11-29  0:00       ` Al Christians
1999-11-29  0:00         ` Lutz Donnerhacke
1999-11-29  0:00           ` Preben Randhol
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox