comp.lang.ada
 help / color / mirror / Atom feed
* Re: float problem
  2002-07-07 15:06 gnat: float problem Jan Prazak
@ 2002-07-07 14:08 ` Frank J. Lhota
  2002-07-08 20:20   ` Jan Prazak
  2002-07-07 21:04 ` gnat: " achrist
  1 sibling, 1 reply; 16+ messages in thread
From: Frank J. Lhota @ 2002-07-07 14:08 UTC (permalink / raw)


The problem is that 0.1 cannot be represented exactly as a floating point
number. When you add 5 copies of 0.1 to 1.0, the error in the representation
of 0.1 is multiplied by 5. The error is small enough to not affect the
printed output, where things are rounded to six significant digits, but it
does result in a value of f that is slightly more than -0.5. You can confirm
this by adding the following statement right before the statement where f
gets incremented by 0.1:

    if f > -0.5 then
        Put_Line ( "f > -0.5, that's the problem!" );
    end if;






^ permalink raw reply	[flat|nested] 16+ messages in thread

* gnat: float problem
@ 2002-07-07 15:06 Jan Prazak
  2002-07-07 14:08 ` Frank J. Lhota
  2002-07-07 21:04 ` gnat: " achrist
  0 siblings, 2 replies; 16+ messages in thread
From: Jan Prazak @ 2002-07-07 15:06 UTC (permalink / raw)


Hello,

I don't know if this is a bug or not, please take a look:

-----------------
with Text_IO; use Text_IO;

procedure my_test is
i : integer;
f : float := -1.0;
package My_int_io is new Integer_IO(integer); use My_int_io;
package My_float_io is new Float_IO(float); use My_float_io;
begin
    new_line;

    for x in 1 .. 6
    loop
        put(f);
        i := integer(f);
        put(i);
        new_line;
        f := f + 0.1;
    end loop;

    new_line;

    put(integer(-0.5)); -- prints "-1"
end;
----------------

OUTPUT:

-1.00000E+00         -1
-9.00000E-01         -1
-8.00000E-01         -1
-7.00000E-01         -1
-6.00000E-01         -1
-5.00000E-01          0

         -1

I know that floating point numbers are not very exact, but this really
looks like a bug, because -5.00000E-01 == -0.5.

Jan




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: gnat: float problem
  2002-07-07 15:06 gnat: float problem Jan Prazak
  2002-07-07 14:08 ` Frank J. Lhota
@ 2002-07-07 21:04 ` achrist
  1 sibling, 0 replies; 16+ messages in thread
From: achrist @ 2002-07-07 21:04 UTC (permalink / raw)


Jan Prazak wrote:
> 
> I know that floating point numbers are not very exact, but this really
> looks like a bug, because -5.00000E-01 == -0.5.

This  is all fairly reasonable, given that 0.1 cannot be exactly
represented as a floating point on a binary machine.  I believe that
this will be rounded and may be approximated as slighltly more than 0.1.
In hexadecimal, this is 0.199999999... I think, so there is a good
chance that rounding will go upward (50% of the less significant bits
being ones).

Question:  0.5 and -0.5 are decimal numbers that can be represented
exactly as floating point.  Is the compiler required to figure this
out?  If it converted 0.5 to binary the dumb way, ie taking 5 times
0.1, it might not get it right.  Which compilers always get this kind
of conversion correct?

Al



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-08 20:20   ` Jan Prazak
@ 2002-07-08 18:10     ` David C. Hoos
  2002-07-09  1:05       ` Robert A Duff
  2002-07-08 18:19     ` Frank J. Lhota
                       ` (4 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: David C. Hoos @ 2002-07-08 18:10 UTC (permalink / raw)


It is impossible for _any_ computer language or compiler to _not_
round when converting to machine representation to decimal
representation, unless the machine representation is decimal --
something that no modern machine does.  This is because only certain
decimal values are _exactly_ representable in binary.  For example
0.1 is not exactly representable in binary, but values like 0.125, 0.375,
etc. are exactly representable.

The issue, then, is the _degree_ of rounding that is done.
In the case of the Ada type Float, most compilers use that type for
32-bit floating point, while 64-bit floating point is implemented
with the type Long_Float.

----- Original Message ----- 
From: "Jan Prazak" <janp9@gmx.net>
Newsgroups: comp.lang.ada
To: <comp.lang.ada@ada.eu.org>
Sent: Monday, July 08, 2002 3:20 PM
Subject: Re: float problem


> On Sun, 07 Jul 2002 13:08:01 -0100, Frank J. Lhota wrote:
> 
> > The error is small enough to
> > not affect the printed output, where things are rounded to six
> > significant digits, ...
> 
> Thanks, I didn't know that procedure "put" rounds given number. I have
> just started to learn Ada, but I was using Pascal (and a bit Delphi)
> before, where there is no rounding in procedure "write".
> BTW: is it possible to disable the rounding in "put"? Maybe with some
> global boolean variable or someting (maybe a pragma).
> 
> _______________________________________________
> comp.lang.ada mailing list
> comp.lang.ada@ada.eu.org
> http://ada.eu.org/mailman/listinfo/comp.lang.ada
> 




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-08 20:20   ` Jan Prazak
  2002-07-08 18:10     ` David C. Hoos
@ 2002-07-08 18:19     ` Frank J. Lhota
  2002-07-08 19:12     ` tmoran
                       ` (3 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Frank J. Lhota @ 2002-07-08 18:19 UTC (permalink / raw)



> Thanks, I didn't know that procedure "put" rounds given number. I have
> just started to learn Ada, but I was using Pascal (and a bit Delphi)
> before, where there is no rounding in procedure "write".

Of course there is, as there is with the output of floating point numbers in
most languages. The internal representation of floating point numbers are
generally in binary format, whereas text output for humans should be in
decimal. To represent the exact value stored in the internal representation
would require dozens of decimal digits, most of which would be inaccurate
due to roundoff errors. In every programming language I know of, the default
is to display only as many decimal digits as can be expected to be accurate.
The number is rounded to this reasonable number of decimal digits.

For 32 bit IEEE floating numbers, one cannot guarantee that more than 6
decimal digits are accurate. That is why the default format for outputting
such numbers only displays 6 decimal digits (1 before the decimal point, 5
after the decimal point)

> BTW: is it possible to disable the rounding in "put"? Maybe with some
> global boolean variable or someting (maybe a pragma).

One way to see more decimal digits would be to increase the value of
My_Float_Io.Default_Aft, e.g.

    My_Float_Io.Default_Aft := 6;

This will change the default Aft for all calls to My_Float_Io.Put. As an
alternative, I would recommend that in the call to Put for f, specify the
AFT parameter and make it something larger than Float'Aft, e.g.

        put(f, Aft => 6);

When I did this in your test program, the problem is shown rather clearly:

-1.000000E+00         -1
-9.000000E-01         -1
-8.000000E-01         -1
-6.999999E-01         -1
-5.999999E-01         -1
-4.999999E-01          0

         -1





^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-08 20:20   ` Jan Prazak
  2002-07-08 18:10     ` David C. Hoos
  2002-07-08 18:19     ` Frank J. Lhota
@ 2002-07-08 19:12     ` tmoran
  2002-07-08 19:28     ` achrist
                       ` (2 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: tmoran @ 2002-07-08 19:12 UTC (permalink / raw)


> ... but I was using Pascal (and a bit Delphi)
> before, where there is no rounding in procedure "write".
  So it must print n decimal digits to correctly represent 1/2**n,
e.g. a 4 byte IEEE float must print 23 digits.
> BTW: is it possible to disable the rounding in "put"? Maybe with some
> global boolean variable or someting (maybe a pragma).
  Look at the "Aft" parameter in Float_IO.Put You can specify how many
digits you want printed to the right (or left) of the decimal point.  You
didn't say, so the compiler used Default_Aft.  Your post showed 5 digits
to the right, so Default_Aft must be 5, so Float'digits is 6 in your
compiler.  Thus all your calculations, and printing, were done to 6 digit
accuracy.  If you want something different from the defaults you will have
to say so in your program.  Defaults are a convencience, but they can also
be a trap for the unwary.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-08 20:20   ` Jan Prazak
                       ` (2 preceding siblings ...)
  2002-07-08 19:12     ` tmoran
@ 2002-07-08 19:28     ` achrist
  2002-07-08 23:00     ` Jan Prazak
  2002-07-08 23:00     ` Jan Prazak
  5 siblings, 0 replies; 16+ messages in thread
From: achrist @ 2002-07-08 19:28 UTC (permalink / raw)


Jan Prazak wrote:
> 
> On Sun, 07 Jul 2002 13:08:01 -0100, Frank J. Lhota wrote:
> 
> > The error is small enough to
> > not affect the printed output, where things are rounded to six
> > significant digits, ...
> 
> Thanks, I didn't know that procedure "put" rounds given number. I have
> just started to learn Ada, but I was using Pascal (and a bit Delphi)
> before, where there is no rounding in procedure "write".
> BTW: is it possible to disable the rounding in "put"? Maybe with some
> global boolean variable or someting (maybe a pragma).

If there was no rounding, then displaying a number with absolute value
less than one would require 1 decimal digit to show each bit to the
right of the decimal (or binary) point.  Short floating point values
(on typical hardware) in Ada or Pascal would require about 24 digits.
Double precision values would require about 53 digits,  and long double
precision would require about 64 digits. 

The 'unrounded' values that you get from Pascal, etc, show the value
to full precision, ie the rightmost digit shown is the one about where
the effects of rounding and truncation error show up, depending on how
much rounding and truncation has happened.  Any digits beyond those
shown are probably of questionable value at best, but that doesn't mean
that there is no rounding to produce the output you see.


Al



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-07 14:08 ` Frank J. Lhota
@ 2002-07-08 20:20   ` Jan Prazak
  2002-07-08 18:10     ` David C. Hoos
                       ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Jan Prazak @ 2002-07-08 20:20 UTC (permalink / raw)


On Sun, 07 Jul 2002 13:08:01 -0100, Frank J. Lhota wrote:

> The error is small enough to
> not affect the printed output, where things are rounded to six
> significant digits, ...

Thanks, I didn't know that procedure "put" rounds given number. I have
just started to learn Ada, but I was using Pascal (and a bit Delphi)
before, where there is no rounding in procedure "write".
BTW: is it possible to disable the rounding in "put"? Maybe with some
global boolean variable or someting (maybe a pragma).




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-08 23:00     ` Jan Prazak
@ 2002-07-08 20:34       ` David C. Hoos
  2002-07-09 13:36       ` Ted Dennison
  1 sibling, 0 replies; 16+ messages in thread
From: David C. Hoos @ 2002-07-08 20:34 UTC (permalink / raw)


You need to read the relevant section of the Ada Language Reference
Manual -- i.e., A.10.9 Input-Output for Real Types

----- Original Message ----- 
From: "Jan Prazak" <janp9@gmx.net>
Newsgroups: comp.lang.ada
To: <comp.lang.ada@ada.eu.org>
Sent: Monday, July 08, 2002 6:00 PM
Subject: Re: float problem


> I forgot to ask someting: is it posible to change the exponent output to
> a "normal" output? It is possible in Pascal.
> 
> I mean I would rather see
> 
> -0.70000
> 
> instead of
> 
> -7.00000E-01
> 
> or this would be even better: simply -0.7
> 
> _______________________________________________
> comp.lang.ada mailing list
> comp.lang.ada@ada.eu.org
> http://ada.eu.org/mailman/listinfo/comp.lang.ada
> 




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-08 20:20   ` Jan Prazak
                       ` (3 preceding siblings ...)
  2002-07-08 19:28     ` achrist
@ 2002-07-08 23:00     ` Jan Prazak
  2002-07-08 23:00     ` Jan Prazak
  5 siblings, 0 replies; 16+ messages in thread
From: Jan Prazak @ 2002-07-08 23:00 UTC (permalink / raw)


OK, thanks to all. Now I remember that there is also a way in Pascal to
define the precision in procedure "write", similar to the "Aft" variable in Ada. So
probably the result would be the same in Pascal.

So
  put(f, Aft => 6);
is the thing a wanted, just to see the (more) precise value.

Jan




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-08 20:20   ` Jan Prazak
                       ` (4 preceding siblings ...)
  2002-07-08 23:00     ` Jan Prazak
@ 2002-07-08 23:00     ` Jan Prazak
  2002-07-08 20:34       ` David C. Hoos
  2002-07-09 13:36       ` Ted Dennison
  5 siblings, 2 replies; 16+ messages in thread
From: Jan Prazak @ 2002-07-08 23:00 UTC (permalink / raw)


I forgot to ask someting: is it posible to change the exponent output to
a "normal" output? It is possible in Pascal.

I mean I would rather see

-0.70000

instead of

-7.00000E-01

or this would be even better: simply -0.7




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-08 18:10     ` David C. Hoos
@ 2002-07-09  1:05       ` Robert A Duff
  2002-07-09  2:14         ` David C. Hoos, Sr.
  0 siblings, 1 reply; 16+ messages in thread
From: Robert A Duff @ 2002-07-09  1:05 UTC (permalink / raw)


"David C. Hoos" <david.c.hoos.sr@ada95.com> writes:

> It is impossible for _any_ computer language or compiler to _not_
> round when converting to machine representation to decimal
> representation, unless the machine representation is decimal --
> something that no modern machine does.  This is because only certain
> decimal values are _exactly_ representable in binary.  For example
> 0.1 is not exactly representable in binary, but values like 0.125, 0.375,
> etc. are exactly representable.

I think you have it backwards.

Every binary value is representable exactly in decimal, so it *is*
possible to display floating point values (whose radix is 2, as is
usual) in decimal without rounding (or truncation or whatever).  You
just need to display enough digits (which will be a finite number).

Your comments apply to the other way 'round (e.g., 'Value of 0.1 cannot
produce an exact floating-point representation of 0.1 -- assuming the
radix is 2).

I just got done reading Volume 2 of Knuth, which I've put off for years,
because I'm much more interested in (say) storage allocation than
numerics stuff.  Anyway, he discusses this issue in problem 4 of section
4.4 (a whole section on "Radix Conversion"!).

- Bob



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-09  1:05       ` Robert A Duff
@ 2002-07-09  2:14         ` David C. Hoos, Sr.
  0 siblings, 0 replies; 16+ messages in thread
From: David C. Hoos, Sr. @ 2002-07-09  2:14 UTC (permalink / raw)



----- Original Message ----- 
From: "Robert A Duff" <bobduff@shell01.TheWorld.com>
Newsgroups: comp.lang.ada
To: <comp.lang.ada@ada.eu.org>
Sent: July 08, 2002 8:05 PM
Subject: Re: float problem


> "David C. Hoos" <david.c.hoos.sr@ada95.com> writes:
> 
> > It is impossible for _any_ computer language or compiler to _not_
> > round when converting to machine representation to decimal
> > representation, unless the machine representation is decimal --
> > something that no modern machine does.  This is because only certain
> > decimal values are _exactly_ representable in binary.  For example
> > 0.1 is not exactly representable in binary, but values like 0.125, 0.375,
> > etc. are exactly representable.
> 
> I think you have it backwards.
> 
Yes, I realized my misstatement after I had punched the "send"
button.  What I had in mind was the usual situation where one uses (say)
15 significant digits to represent the value of a 64-bit floating point
item.  The real point there is that since the binary value is in all
liklihood inexact, any digits decimal beyond 15 are uncertain.

If, on the other hand, the binary value is presumed exact, then the
fractional part of the decimal representation can be exactly done
with one decimal digit for every bit in the binary fraction.

> Every binary value is representable exactly in decimal, so it *is*
> possible to display floating point values (whose radix is 2, as is
> usual) in decimal without rounding (or truncation or whatever).  You
> just need to display enough digits (which will be a finite number).
> 
> Your comments apply to the other way 'round (e.g., 'Value of 0.1 cannot
> produce an exact floating-point representation of 0.1 -- assuming the
> radix is 2).
> 
> I just got done reading Volume 2 of Knuth, which I've put off for years,
> because I'm much more interested in (say) storage allocation than
> numerics stuff.  Anyway, he discusses this issue in problem 4 of section
> 4.4 (a whole section on "Radix Conversion"!).
> 
> - Bob
> _______________________________________________
> comp.lang.ada mailing list
> comp.lang.ada@ada.eu.org
> http://ada.eu.org/mailman/listinfo/comp.lang.ada
> 
> 





^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-08 23:00     ` Jan Prazak
  2002-07-08 20:34       ` David C. Hoos
@ 2002-07-09 13:36       ` Ted Dennison
  2002-07-09 19:03         ` Jeffrey Carter
  2002-07-09 20:07         ` Robert Dewar
  1 sibling, 2 replies; 16+ messages in thread
From: Ted Dennison @ 2002-07-09 13:36 UTC (permalink / raw)


Jan Prazak <janp9@gmx.net> wrote in message news:<pan.2002.07.08.21.58.02.911937.7736@gmx.net>...
> I forgot to ask someting: is it posible to change the exponent output to
> a "normal" output? It is possible in Pascal.
> 
> I mean I would rather see
> 
> -0.70000
> 
> instead of
> 
> -7.00000E-01
> 
> or this would be even better: simply -0.7

Some compilers will do that if you convert the floating-point value
into a fixed-point value (eg: Duration), and dispaly that.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-09 13:36       ` Ted Dennison
@ 2002-07-09 19:03         ` Jeffrey Carter
  2002-07-09 20:07         ` Robert Dewar
  1 sibling, 0 replies; 16+ messages in thread
From: Jeffrey Carter @ 2002-07-09 19:03 UTC (permalink / raw)


Ted Dennison wrote:
> 
> Jan Prazak <janp9@gmx.net> wrote in message news:<pan.2002.07.08.21.58.02.911937.7736@gmx.net>...
> > I forgot to ask someting: is it posible to change the exponent output to
> > a "normal" output? It is possible in Pascal.
> >
> > I mean I would rather see
> >
> > -0.70000
> >
> > instead of
> >
> > -7.00000E-01
> >
> > or this would be even better: simply -0.7
> 
> Some compilers will do that if you convert the floating-point value
> into a fixed-point value (eg: Duration), and dispaly that.

Call Put with Exp => 0.

-- 
Jeff Carter
"I unclog my nose towards you."
Monty Python & the Holy Grail



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: float problem
  2002-07-09 13:36       ` Ted Dennison
  2002-07-09 19:03         ` Jeffrey Carter
@ 2002-07-09 20:07         ` Robert Dewar
  1 sibling, 0 replies; 16+ messages in thread
From: Robert Dewar @ 2002-07-09 20:07 UTC (permalink / raw)


dennison@telepath.com (Ted Dennison) wrote in message news:<4519e058.0207090536.55f497f0@posting.google.com>...

> Some compilers will do that if you convert the floating-point value
> into a fixed-point value (eg: Duration), and dispaly that.

This is a bizarre and misleading answer. The semantics
of conversion from float to fixed and the semantics for
display of fixed point compilers is precisely defined,
there is no room for "some compilers" to do something
different from other compilers here.

Furthermore, this makes no sense. If you want to format
your float output a certain way, use the parameters provided to Put
for this purpose, there is absolutely
no sense in going through fixed point.



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2002-07-09 20:07 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-07 15:06 gnat: float problem Jan Prazak
2002-07-07 14:08 ` Frank J. Lhota
2002-07-08 20:20   ` Jan Prazak
2002-07-08 18:10     ` David C. Hoos
2002-07-09  1:05       ` Robert A Duff
2002-07-09  2:14         ` David C. Hoos, Sr.
2002-07-08 18:19     ` Frank J. Lhota
2002-07-08 19:12     ` tmoran
2002-07-08 19:28     ` achrist
2002-07-08 23:00     ` Jan Prazak
2002-07-08 23:00     ` Jan Prazak
2002-07-08 20:34       ` David C. Hoos
2002-07-09 13:36       ` Ted Dennison
2002-07-09 19:03         ` Jeffrey Carter
2002-07-09 20:07         ` Robert Dewar
2002-07-07 21:04 ` gnat: " achrist

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