comp.lang.ada
 help / color / mirror / Atom feed
* Truncation of FLOAT values
@ 1996-04-18  0:00 Franz Kruse
  1996-04-18  0:00 ` Cordes MJ
  0 siblings, 1 reply; 10+ messages in thread
From: Franz Kruse @ 1996-04-18  0:00 UTC (permalink / raw)



Is there a simple way in Ada 83 to determine the integer part or the fraction part
of a FLOAT value?

A conversion to INTEGER cannot be used, because it rounds.

Franz Kruse






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

* Re: Truncation of FLOAT values
  1996-04-18  0:00 Truncation of FLOAT values Franz Kruse
@ 1996-04-18  0:00 ` Cordes MJ
  1996-04-19  0:00   ` Robert Dewar
                     ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Cordes MJ @ 1996-04-18  0:00 UTC (permalink / raw)


Franz Kruse (Franz.Kruse@erno.de) wrote:

: Is there a simple way in Ada 83 to determine the integer part or the fraction part
: of a FLOAT value?

: A conversion to INTEGER cannot be used, because it rounds.

: Franz Kruse

If your compiler rounds, then you can simply add 0.5 to the FLOAT value
prior to converting it an INTEGER. You get the fractional part by 
converting the result back to FLOAT and subtracting it from the 
original FLOAT value.

Seems pretty simple to me (although it doesn't use any fancy Ada
features)  ;)

P.S., take care to check how your compiler rounds for numbers less
than zero and how it rounds (with the addition of 0.5) at the upper
and lower limits of the valid range.

Mike Cordes
###





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

* Re: Truncation of FLOAT values
  1996-04-19  0:00   ` John Herro
@ 1996-04-19  0:00     ` Robert Dewar
  1996-04-22  0:00       ` John Herro
  1996-04-22  0:00     ` Robert I. Eachus
  1 sibling, 1 reply; 10+ messages in thread
From: Robert Dewar @ 1996-04-19  0:00 UTC (permalink / raw)


John Herro said

"function Floor(X : in Float) return Integer is
   Answer : Integer := Integer(X);
begin
   if Float(Answer) > X then
      Answer := Answer - 1;
   end if;
   return Answer;
end Floor;"

Although this will typically work, Ada semantics do not guarantee that
it will work.

X may not be a model number, suppose that in fact X is
1.99999999999999999999999999999999

representing a number that is less than the model number 2.0, but
greater than the largest model number less than 2.0. 

Now answer will surely be 2

Float(Answer) is the model number 2.0

but since x is not a model number, it can be treated as though it were
any number in its model interval, and in particular as 2.0, so that
the test may yield false and the final restul returned is 2 instead
of 1.

You can actually imagine this happening with some scenarios of extended
values being passed in registers.


Floating-point semantics are very delicate :-)





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

* Re: Truncation of FLOAT values
  1996-04-18  0:00 ` Cordes MJ
@ 1996-04-19  0:00   ` Robert Dewar
  1996-04-20  0:00     ` Cordes MJ
  1996-04-19  0:00   ` John Herro
  1996-04-19  0:00   ` Peter Hermann
  2 siblings, 1 reply; 10+ messages in thread
From: Robert Dewar @ 1996-04-19  0:00 UTC (permalink / raw)


Mike said

"If your compiler rounds, then you can simply add 0.5 to the FLOAT value
prior to converting it an INTEGER. You get the fractional part by
converting the result back to FLOAT and subtracting it from the
original FLOAT value."

First, you clearly meant to say subtract rather than round,

e.g. 2.3 - 0.5 = 1.8, conversion rounds to 2 = integer part of 2.3

but that's wrong, because

3.0 - 0.5 = 2.5, which is allowed in Ada 83 to round to 2 when you want 3.

There is no trivial solution  to this in Ada 83, which is why the
truncation attribues was added to Ada 95.





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

* Re: Truncation of FLOAT values
  1996-04-18  0:00 ` Cordes MJ
  1996-04-19  0:00   ` Robert Dewar
  1996-04-19  0:00   ` John Herro
@ 1996-04-19  0:00   ` Peter Hermann
  2 siblings, 0 replies; 10+ messages in thread
From: Peter Hermann @ 1996-04-19  0:00 UTC (permalink / raw)


Cordes MJ (l117593@cliffy.lfwc.lockheed.com) wrote:
: Franz Kruse (Franz.Kruse@erno.de) wrote:
: : Is there a simple way in Ada 83 to determine the integer part or the fraction part
: : of a FLOAT value?
: : A conversion to INTEGER cannot be used, because it rounds.
: If your compiler rounds, then you can simply add 0.5 to the FLOAT value
: prior to converting it an INTEGER. You get the fractional part by 
: converting the result back to FLOAT and subtracting it from the 
: original FLOAT value.

I am looking into LRM A.5.3(18-62)
Why not using such attributes like fraction, compose,floor,ceiling,etc. etc. ?

--
Peter Hermann  Tel:+49-711-685-3611 Fax:3758 ph@csv.ica.uni-stuttgart.de
Pfaffenwaldring 27, 70569 Stuttgart Uni Computeranwendungen
Team Ada: "C'mon people let the world begin" (Paul McCartney)




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

* Re: Truncation of FLOAT values
  1996-04-18  0:00 ` Cordes MJ
  1996-04-19  0:00   ` Robert Dewar
@ 1996-04-19  0:00   ` John Herro
  1996-04-19  0:00     ` Robert Dewar
  1996-04-22  0:00     ` Robert I. Eachus
  1996-04-19  0:00   ` Peter Hermann
  2 siblings, 2 replies; 10+ messages in thread
From: John Herro @ 1996-04-19  0:00 UTC (permalink / raw)


Franz.Kruse@erno.de (Franz Kruse) writes:
> Is there a simple way in Ada 83 to determine
> the integer part or the fraction part of a FLOAT
> value?  A conversion to INTEGER cannot be
> used, because it rounds.

     Here are two functions from my Ada Tutor program that will work in
Ada 83.  The two functions behave the same for positive Floats but
differently for negative Floats.  This first function Floor computes the
largest Integer less than or equal to a given Float, always truncating
toward negative infinity:

function Floor(X : in Float) return Integer is
   Answer : Integer := Integer(X);
begin
   if Float(Answer) > X then
      Answer := Answer - 1;
   end if;
   return Answer;
end Floor;

This second function always truncates toward zero:

function Truncate(X : in Float) return Integer is
   Answer : Integer := Integer(X);
begin
   if Answer > 0 and Float(Answer) > X then
      Answer := Answer - 1;
   elsif Answer < 0 and Float(Answer) < X then
      Answer := Answer + 1;
   end if;
   return Answer;
end Truncate;

     Needless to say, getting the fractional part of a Float after you
have the Integer part is trivial - just convert the Integer back to Float
and subtract from the original number.  I hope this helps.
- John Herro
Software Innovations Technology
http://members.aol.com/AdaTutor
ftp://members.aol.com/AdaTutor




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

* Re: Truncation of FLOAT values
  1996-04-19  0:00   ` Robert Dewar
@ 1996-04-20  0:00     ` Cordes MJ
  1996-04-21  0:00       ` Robert Dewar
  0 siblings, 1 reply; 10+ messages in thread
From: Cordes MJ @ 1996-04-20  0:00 UTC (permalink / raw)


Robert Dewar (dewar@cs.nyu.edu) wrote:

: First, you clearly meant to say subtract rather than round,

oops!

: e.g. 2.3 - 0.5 = 1.8, conversion rounds to 2 = integer part of 2.3

: but that's wrong, because

: 3.0 - 0.5 = 2.5, which is allowed in Ada 83 to round to 2 when you want 3.

Unless you are telling me that single implementation of an Ada compiler
_may_, in practice, round 2.5 to 3 and round 3.5 to 3, you can write
an implementation specific solution. However, in the case where a 
compiler does round x.5 to x (and not x+1), the solution is less
simple.

: There is no trivial solution  to this in Ada 83, which is why the
: truncation attribues was added to Ada 95.


--
---------------------------------------------------------------------
Michael J Cordes
Phone: (817) 935-3823
Fax:   (817) 935-3800
EMail: CordesMJ@lfwc.lockheed.com
---------------------------------------------------------------------




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

* Re: Truncation of FLOAT values
  1996-04-20  0:00     ` Cordes MJ
@ 1996-04-21  0:00       ` Robert Dewar
  0 siblings, 0 replies; 10+ messages in thread
From: Robert Dewar @ 1996-04-21  0:00 UTC (permalink / raw)


Michael said:

"Unless you are telling me that single implementation of an Ada compiler
_may_, in practice, round 2.5 to 3 and round 3.5 to 3, you can write
an implementation specific solution. However, in the case where a
compiler does round x.5 to x (and not x+1), the solution is less
simple."

  That seems unlikely, but rounding 2.5 to 2 and 3.5 to 4 is not only
  allowed, but likely to be encountered in practice (e.g. the Alsys
  compiler for the 386 did this). This style of rounding is called
  unbiased rounding, and corresponds to IEEE round-to-nearest-even.
  Ada 95 forbids this kind of rounding (unless you use the specific
  attribute), but Ada 83 certainly allows it.

Also, note my discussion of problems with non-model numbers.





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

* Re: Truncation of FLOAT values
  1996-04-19  0:00   ` John Herro
  1996-04-19  0:00     ` Robert Dewar
@ 1996-04-22  0:00     ` Robert I. Eachus
  1 sibling, 0 replies; 10+ messages in thread
From: Robert I. Eachus @ 1996-04-22  0:00 UTC (permalink / raw)


In article <dewar.829958772@schonberg> dewar@cs.nyu.edu (Robert Dewar) writes:

  > John Herro said

  > "function Floor(X : in Float) return Integer is
  >    Answer : Integer := Integer(X);
  > begin
  >    if Float(Answer) > X then
  >	  Answer := Answer - 1;
  >    end if;
  >    return Answer;
  > end Floor;"

  > Although this will typically work, Ada semantics do not guarantee that
  > it will work.
 
   While Professer Dewar is quite correct, a more helpful answer is:

    function Floor(X : in Float) return Integer is
      Answer : Integer;
    begin
      Answer := Integer(X);
      if Float(Answer) - X > 0.0 then return Answer - 1; end if;
      return Answer;
   exception
     when Constraint_Error =>
      if  X - Float(Integer'LAST - 1) > 0.0
      then if X - Float(Integer'LAST) < 0.0
           then return Integer'LAST - 1;
           elsif X - Float(Integer'LAST) < 1.0
           then return Integer'LAST;
           else raise;
           end if;
      elsif Float(Integer'FIRST + 1) - X < 0.0
      then if Float(Integer'FIRST) - X >= 0.0
      then return Integer'FIRST;
      else raise;
      end if;
   end Floor;

   Almost all floating point compares are against zero, the exception
is the case where you are testing for X < Integer'LAST + 1 in the
three special cases dealt with in the exception handler.  Yes, there
are still cases where the result returned by this function will not be
"mathematically correct" but they will only occur when X is converted
to a model number whose fractional part is zero as a side effect of
the call.  In other words on most hardware, Floor(1_000_000_000.0 -
Float'Epsilon) will return 1_000_000_000.  (On most other
implementations, it will raise an exception.)  This is a known problem
with any implementation of floating point arithmetic, and has to be
dealt with in the design of floating point algorithms.

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




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

* Re: Truncation of FLOAT values
  1996-04-19  0:00     ` Robert Dewar
@ 1996-04-22  0:00       ` John Herro
  0 siblings, 0 replies; 10+ messages in thread
From: John Herro @ 1996-04-22  0:00 UTC (permalink / raw)


dewar@cs.nyu.edu (Robert Dewar) writes:
> Although [John Herro's Floor function for Ada
> 83] will typically work, Ada semantics do not
> guarantee that it will work.  X may not be a
> model number, suppose that in fact X is
> 1.99999999999999999999999999999999
> ..... [The Floor function may give a wrong
> answer in cases like this.]
     An interesting case!  In my next revision of Ada Tutor, I'll mention
this fact, and also mention the truncation attributes of Ada 95.
     I have to say that I've learned a lot hanging around comp.lang.ada,
and in many cases this newsgroup has helped me to improve my Ada Tutor
program.  Thanks to everybody!  (Needless to say, I'll announce here when
the next revision of Ada Tutor is released.)
- John Herro
Software Innovations Technology
http://members.aol.com/AdaTutor
ftp://members.aol.com/AdaTutor




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

end of thread, other threads:[~1996-04-22  0:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-04-18  0:00 Truncation of FLOAT values Franz Kruse
1996-04-18  0:00 ` Cordes MJ
1996-04-19  0:00   ` Robert Dewar
1996-04-20  0:00     ` Cordes MJ
1996-04-21  0:00       ` Robert Dewar
1996-04-19  0:00   ` John Herro
1996-04-19  0:00     ` Robert Dewar
1996-04-22  0:00       ` John Herro
1996-04-22  0:00     ` Robert I. Eachus
1996-04-19  0:00   ` Peter Hermann

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