comp.lang.ada
 help / color / mirror / Atom feed
* When floating point result intervals span the boundary - what value is selected?
@ 2006-03-03  1:30 Justin Gombos
  2006-03-03  2:55 ` haley
  2006-03-03  5:51 ` Jeffrey R. Carter
  0 siblings, 2 replies; 6+ messages in thread
From: Justin Gombos @ 2006-03-03  1:30 UTC (permalink / raw)


Question for the language lawyers-

Suppose you have the type:

   type Sine_Type is digits 6 range -1.0..1.0;

You perform an operation on two objects of this type, and the
mathematical result is exactly 1.0, so the result interval is
/partially/ in range.  Is there any guarantee that the stored result
will be in range?

It would be unreasonable for a compiler to select the next highest
model number, but it seems the language allows it.  The Ada LRM
<http://www.adaic.org/standards/95lrm/html/RM-G-2-1.html> seems to
make no guarantees - leaving it up to the compiler (whenever
T'Machine_Overflows is false).  The GNAT manual doesn't state either
way what it does.

This code raises some more questions:

   with Ada.Text_IO;

   procedure Tiny_Real is

      type Sine_Type is digits 6 range -1.0..1.0;

      Oversized : Sine_Type := Sine_Type'Last + Sine_Type'Small;

      Well_Oversized : constant Float := Float(Sine_Type'Last) + Float(Sine_Type'Small * 500000.0);

   begin

      Ada.Text_IO.Put ("The smallest possible float is " & Float'Image(Float'Small));
      Ada.Text_IO.New_Line;

      -- Strangely, the smallest possible float can be reduced even more.
      -- Could it be that the value is in a register, thus capable of
      -- representing fractional model number sizes?
      --
      Ada.Text_IO.Put ("A quarter of that is " & Float'Image(Float'Small / 4.0));
      Ada.Text_IO.New_Line;

      -- I was expecting this to report a model number close to 1.0, not 3.40282E+38.
      --
      Ada.Text_IO.Put ("Safe_Last is " & Float'Image(Sine_Type'Safe_Last));
      Ada.Text_IO.New_Line;

      Ada.Text_IO.Put ("Oversized is " & Float'Image(Float(Oversized)));

      -- I was expecting this to throw a constraint error:
      --
      Oversized := Sine_Type(Well_Oversized);

      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put ("Oversized is " & Float'Image(Float(Oversized)));

   end Tiny_Real;

The output:

   The smallest possible float is  2.58494E-26
   A quarter of that is  6.46235E-27
   Safe_Last is  3.40282E+38
   Oversized is  1.00000E+00
   Oversized is  1.00000E+00

-- 
PM instructions: do a C4esar Ciph3r on my address; retain punctuation.



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

* Re: When floating point result intervals span the boundary - what value is selected?
  2006-03-03  1:30 When floating point result intervals span the boundary - what value is selected? Justin Gombos
@ 2006-03-03  2:55 ` haley
  2006-03-03  5:51 ` Jeffrey R. Carter
  1 sibling, 0 replies; 6+ messages in thread
From: haley @ 2006-03-03  2:55 UTC (permalink / raw)


S'Safe_First
Yields the lower bound of the safe range (see 3.5.7) of the type T. If
the Numerics Annex is not supported, the value of this attribute is
implementation defined; see G.2.2 for the definition that applies to
implementations supporting the Numerics Annex. The value of this
attribute is of the type universal_real.
quoted from http://www.grammatech.com/rm95html-1.0/rm9x-G-02-02.html




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

* Re: When floating point result intervals span the boundary - what value is selected?
  2006-03-03  1:30 When floating point result intervals span the boundary - what value is selected? Justin Gombos
  2006-03-03  2:55 ` haley
@ 2006-03-03  5:51 ` Jeffrey R. Carter
  2006-03-04 16:46   ` Justin Gombos
  1 sibling, 1 reply; 6+ messages in thread
From: Jeffrey R. Carter @ 2006-03-03  5:51 UTC (permalink / raw)


Justin Gombos wrote:

> Question for the language lawyers-
> 
> Suppose you have the type:
> 
> type Sine_Type is digits 6 range -1.0..1.0;

You need to remember the distinction between a type and a subtype. The name in a
type declaration is the first-named subtype. Your declaration is equivalent to

type Sine_Type'Base is digits X;

subtype Sine_Type is Sine_Type'Base range -1.0 .. 1.0;

where X >= 6. Sine_Type'Base is an unconstrained floating-point type that makes 
sense for your hardware.

> Oversized : Sine_Type := Sine_Type'Last + Sine_Type'Small;

This is odd; 'Small is defined only for fixed-point types (ARM K). Maybe this is 
compiler specific. You should probably use 'Model_Small.

Anyway, since 'Small gives 2.58494E-26 and you probably have 6 digits of 
accuracy, 1.0 + 'Small = 1.0. Remember that "+" is defined for the base type.

> Well_Oversized : constant Float := Float(Sine_Type'Last) +
>                                    Float(Sine_Type'Small * 500000.0);

Similarly here, 5.0E5 * 2.58494E-26 ~ 1.3E-20, and 1.0 + 1.3E-20 = 1.0 with 6 
digits of accuracy.

> -- I was expecting this to report a model number close to 1.0, not
> 3.40282E+38. -- 
 > Ada.Text_IO.Put ("Safe_Last is " &
>                  Float'Image(Sine_Type'Safe_Last));

For a subtype S of a floating-point type T, S'Safe_Last "Yields the upper bound
of the safe range of T." (ARM G.2.2). In your case, T is Sine_Type'Base, and its
upper bound is much larger than 1.0.

> Oversized := Sine_Type(Well_Oversized);

Since Well_Oversized is 1.0, there's no problem here. Even if you had a floating 
point type with enough digits to represent 1.0 + 1.3E-20 as different from 1.0, 
the conversion to Sine_Type'Base would result in a value of 1.0.

-- 
Jeff Carter
"You cheesy lot of second-hand electric donkey-bottom biters."
Monty Python & the Holy Grail
14



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

* Re: When floating point result intervals span the boundary - what value is selected?
  2006-03-03  5:51 ` Jeffrey R. Carter
@ 2006-03-04 16:46   ` Justin Gombos
  2006-03-05 19:12     ` Jeff Carter
  2006-03-05 19:13     ` Jeff Carter
  0 siblings, 2 replies; 6+ messages in thread
From: Justin Gombos @ 2006-03-04 16:46 UTC (permalink / raw)


On 2006-03-03, Jeffrey R. Carter <spam@spam.com> wrote:
> Justin Gombos wrote:
>
>> Oversized : Sine_Type := Sine_Type'Last + Sine_Type'Small;
>
> This is odd; 'Small is defined only for fixed-point types (ARM
> K). Maybe this is compiler specific. You should probably use
> 'Model_Small.
>
> Anyway, since 'Small gives 2.58494E-26 and you probably have 6
> digits of accuracy, 1.0 + 'Small = 1.0. Remember that "+" is defined
> for the base type.

I repeated the experiment adding Sine_Type'Model_Small instead.  If
Sine_Type'Last is the highest possible model number in the set, how is
it possible to add Sine_Type'Model_Small to that without throwing a
constraint error?  While I expect the "+" operation to complete
because it's working with Sine_Type'Base, I expect the assignment of
that result to Oversized to fail.  It must be converted back to a
model number prior to storage, and the resulting model number is out
of range.

>> Well_Oversized : constant Float := Float(Sine_Type'Last) +
>>                                    Float(Sine_Type'Small * 500000.0);
>
> Similarly here, 5.0E5 * 2.58494E-26 ~ 1.3E-20, and 1.0 + 1.3E-20 =
> 1.0 with 6 digits of accuracy.

What exactly is going on in this case?  The calculations must produce
a result that is greater than 1.0, at least initially.  Is the runtime
logic rounding toward zero when the difference is within accuracy
constraints?  Does an Ada compiler have the option to throw a
constraint error?

I know I'm missing something here, because I expect the following two
lines to have the exact same result:

   Oversized : Sine_Type := Sine_Type'Last + Sine_Type'Model_Number;
   Oversized : Sine_Type := Sine_Type'Succ(Sine_Type'Last);

The first line runs without error, and the second line throws a
constraint error.

-- 
PM instructions: do a C4esar Ciph3r on my address; retain punctuation.



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

* Re: When floating point result intervals span the boundary - what value is selected?
  2006-03-04 16:46   ` Justin Gombos
@ 2006-03-05 19:12     ` Jeff Carter
  2006-03-05 19:13     ` Jeff Carter
  1 sibling, 0 replies; 6+ messages in thread
From: Jeff Carter @ 2006-03-05 19:12 UTC (permalink / raw)



Justin Gombos wrote:
>
> I repeated the experiment adding Sine_Type'Model_Small instead.  If
> Sine_Type'Last is the highest possible model number in the set, how is
> it possible to add Sine_Type'Model_Small to that without throwing a
> constraint error?  While I expect the "+" operation to complete
> because it's working with Sine_Type'Base, I expect the assignment of
> that result to Oversized to fail.  It must be converted back to a
> model number prior to storage, and the resulting model number is out
> of range.

In Ada, exceptions are raised. Please do not use "throw" when
discussing Ada exceptions.

No. Floating-point operations only deal with a fixed number of bits in
the mantissa. This gives at least the decimal number of digits given in
the type declaration. When you add 2 numbers with different exponents,
the smaller one is scaled to have the same exponent as the larger one
before adding. When a small number like 1.0E-20 is scaled to match a
much larger number like 1.0, the smaller number becomes zero. Thus, the
result of the addition is 1.0.

> What exactly is going on in this case?  The calculations must produce
> a result that is greater than 1.0, at least initially.

No, they don't.

> I know I'm missing something here, because I expect the following two
> lines to have the exact same result:
>
>    Oversized : Sine_Type := Sine_Type'Last + Sine_Type'Model_Number;
>    Oversized : Sine_Type := Sine_Type'Succ(Sine_Type'Last);
>
> The first line runs without error, and the second line throws a
> constraint error.

The first line adds zero to 1.0, giving 1.0, as described above. The
second line yields the next model number of the base type > 1.0. This
number exists, but is not in the range of the subtype, so
Constraint_Error is raised.

--
Jeff Carter
jrcarter commercial-at adm [period | full stop] org




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

* Re: When floating point result intervals span the boundary - what value is selected?
  2006-03-04 16:46   ` Justin Gombos
  2006-03-05 19:12     ` Jeff Carter
@ 2006-03-05 19:13     ` Jeff Carter
  1 sibling, 0 replies; 6+ messages in thread
From: Jeff Carter @ 2006-03-05 19:13 UTC (permalink / raw)



Justin Gombos wrote:
>
> I repeated the experiment adding Sine_Type'Model_Small instead.  If
> Sine_Type'Last is the highest possible model number in the set, how is
> it possible to add Sine_Type'Model_Small to that without throwing a
> constraint error?  While I expect the "+" operation to complete
> because it's working with Sine_Type'Base, I expect the assignment of
> that result to Oversized to fail.  It must be converted back to a
> model number prior to storage, and the resulting model number is out
> of range.

In Ada, exceptions are raised. Please do not use "throw" when
discussing Ada exceptions.

No. Floating-point operations only deal with a fixed number of bits in
the mantissa. This gives at least the decimal number of digits given in
the type declaration. When you add 2 numbers with different exponents,
the smaller one is scaled to have the same exponent as the larger one
before adding. When a small number like 1.0E-20 is scaled to match a
much larger number like 1.0, the smaller number becomes zero. Thus, the
result of the addition is 1.0.

> What exactly is going on in this case?  The calculations must produce
> a result that is greater than 1.0, at least initially.

No, they don't.

> I know I'm missing something here, because I expect the following two
> lines to have the exact same result:
>
>    Oversized : Sine_Type := Sine_Type'Last + Sine_Type'Model_Number;
>    Oversized : Sine_Type := Sine_Type'Succ(Sine_Type'Last);
>
> The first line runs without error, and the second line throws a
> constraint error.

The first line adds zero to 1.0, giving 1.0, as described above. The
second line yields the next model number of the base type > 1.0. This
number exists, but is not in the range of the subtype, so
Constraint_Error is raised.

--
Jeff Carter
jrcarter commercial-at acm [period | full stop] org




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

end of thread, other threads:[~2006-03-05 19:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-03  1:30 When floating point result intervals span the boundary - what value is selected? Justin Gombos
2006-03-03  2:55 ` haley
2006-03-03  5:51 ` Jeffrey R. Carter
2006-03-04 16:46   ` Justin Gombos
2006-03-05 19:12     ` Jeff Carter
2006-03-05 19:13     ` Jeff Carter

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