* Saturation arithmetic woes.
@ 2009-07-29 17:03 xorque
2009-07-29 17:13 ` Martin
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: xorque @ 2009-07-29 17:03 UTC (permalink / raw)
generic
type Discrete_Type is (<>);
package Saturation is
type Saturated_Type is new Discrete_Type;
function "+"
(Left : Saturated_Type;
Right : Saturated_Type) return Saturated_Type;
end Saturation;
package body Saturation is
function "+"
(Left : Saturated_Type;
Right : Saturated_Type) return Saturated_Type
is
Temp_Left : constant Discrete_Type := Discrete_Type (Left);
Temp_Right : constant Discrete_Type := Discrete_Type (Right);
begin
if Temp_Left + Temp_Right > Discrete_Type'Last then
return Saturated_Type (Discrete_Type'Last);
end if;
if Temp_Left + Temp_Right < Discrete_Type'First then
return Saturated_Type (Discrete_Type'First);
end if;
return Saturated_Type (Temp_Left + Temp_Right);
end "+";
end Saturation;
with Saturation;
with Ada.Text_IO;
procedure Main is
type T is range 1 .. 10;
package T_Saturated is new Saturation (T);
package IO renames Ada.Text_IO;
package TIO is new Ada.Text_IO.Integer_IO
(T_Saturated.Saturated_Type);
use type T_Saturated.Saturated_Type;
X : constant T_Saturated.Saturated_Type := 5;
Y : constant T_Saturated.Saturated_Type := 9;
begin
TIO.Put (X + Y); -- 10
IO.New_Line;
end Main;
saturation.adb:10:18: there is no applicable operator "+" for type
"Discrete_Type" defined at saturation.ads:2
saturation.adb:13:18: there is no applicable operator "+" for type
"Discrete_Type" defined at saturation.ads:2
saturation.adb:17:38: there is no applicable operator "+" for type
"Discrete_Type" defined at saturation.ads:2
I'm afraid I'm not well versed in the rules regarding operator name
resolution...
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Saturation arithmetic woes.
2009-07-29 17:03 Saturation arithmetic woes xorque
@ 2009-07-29 17:13 ` Martin
2009-07-29 18:14 ` Jeffrey R. Carter
2009-07-29 19:14 ` Niklas Holsti
2 siblings, 0 replies; 7+ messages in thread
From: Martin @ 2009-07-29 17:13 UTC (permalink / raw)
On Jul 29, 6:03 pm, xorque <xorquew...@googlemail.com> wrote:
> generic
> type Discrete_Type is (<>);
>
> package Saturation is
>
> type Saturated_Type is new Discrete_Type;
>
> function "+"
> (Left : Saturated_Type;
> Right : Saturated_Type) return Saturated_Type;
>
> end Saturation;
>
> package body Saturation is
>
> function "+"
> (Left : Saturated_Type;
> Right : Saturated_Type) return Saturated_Type
> is
> Temp_Left : constant Discrete_Type := Discrete_Type (Left);
> Temp_Right : constant Discrete_Type := Discrete_Type (Right);
> begin
> if Temp_Left + Temp_Right > Discrete_Type'Last then
> return Saturated_Type (Discrete_Type'Last);
> end if;
> if Temp_Left + Temp_Right < Discrete_Type'First then
> return Saturated_Type (Discrete_Type'First);
> end if;
>
> return Saturated_Type (Temp_Left + Temp_Right);
> end "+";
>
> end Saturation;
>
> with Saturation;
> with Ada.Text_IO;
>
> procedure Main is
> type T is range 1 .. 10;
>
> package T_Saturated is new Saturation (T);
> package IO renames Ada.Text_IO;
> package TIO is new Ada.Text_IO.Integer_IO
> (T_Saturated.Saturated_Type);
>
> use type T_Saturated.Saturated_Type;
>
> X : constant T_Saturated.Saturated_Type := 5;
> Y : constant T_Saturated.Saturated_Type := 9;
> begin
> TIO.Put (X + Y); -- 10
> IO.New_Line;
> end Main;
>
> saturation.adb:10:18: there is no applicable operator "+" for type
> "Discrete_Type" defined at saturation.ads:2
> saturation.adb:13:18: there is no applicable operator "+" for type
> "Discrete_Type" defined at saturation.ads:2
> saturation.adb:17:38: there is no applicable operator "+" for type
> "Discrete_Type" defined at saturation.ads:2
>
> I'm afraid I'm not well versed in the rules regarding operator name
> resolution...
generic
type Discrete_Type is (<>);
with function "+" (L, R : Discrete_Type) return Discrete_Type is <>;
package Saturation is
You need to provide a suitable "+" operator.
Cheers
-- Martin
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Saturation arithmetic woes.
2009-07-29 17:03 Saturation arithmetic woes xorque
2009-07-29 17:13 ` Martin
@ 2009-07-29 18:14 ` Jeffrey R. Carter
2009-07-29 19:14 ` Niklas Holsti
2 siblings, 0 replies; 7+ messages in thread
From: Jeffrey R. Carter @ 2009-07-29 18:14 UTC (permalink / raw)
xorque wrote:
> generic
> type Discrete_Type is (<>);
This may be any discrete type, including an enumeration type. Arithmetic is not
defined for enumeration types, so you do not automatically get "+" for this. You
either need to explicitly require a "+" function ("with function "+" ...), or
use a generic formal type that does include "+": "is range <>" or "is mod <>".
--
Jeff Carter
"What I wouldn't give for a large sock with horse manure in it."
Annie Hall
42
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Saturation arithmetic woes.
2009-07-29 17:03 Saturation arithmetic woes xorque
2009-07-29 17:13 ` Martin
2009-07-29 18:14 ` Jeffrey R. Carter
@ 2009-07-29 19:14 ` Niklas Holsti
2009-07-29 19:39 ` xorque
2009-07-30 9:09 ` Jean-Pierre Rosen
2 siblings, 2 replies; 7+ messages in thread
From: Niklas Holsti @ 2009-07-29 19:14 UTC (permalink / raw)
In addition to the replies from Martin and Dmitry regarding the absence
of a "+" operator for Discrete_Type, I would like to comment on the
logic of your saturated-"+":
xorque wrote:
> package body Saturation is
>
> function "+"
> (Left : Saturated_Type;
> Right : Saturated_Type) return Saturated_Type
> is
> Temp_Left : constant Discrete_Type := Discrete_Type (Left);
> Temp_Right : constant Discrete_Type := Discrete_Type (Right);
> begin
> if Temp_Left + Temp_Right > Discrete_Type'Last then
Depending on the actual type associated with Discrete_Type (and assuming
you use the predefined "+" for that type), you risk getting an overflow
on Temp_Left + Temp_Right. If you have overflow checks disabled (as Gnat
has by default) the sum may "wrap around" and seem to be less than
Discrete_Type'Last, giving you the wrong result. If you have overflow
checks enabled, you get a Constraint_Error instead of
Discrete_Type'Last. Ditto for underflow and Discrete_Type'First.
One option is to have two formal types, one that defines the range for
saturation (as Discrete_Type in your code) and another that is wide
enough to compute the sum of Left and Right without under- or overflow.
If the other type is called Wide_Type, you could then replace Temp_Left
and Temp_Right with
Sum : constant Wide_Type := Wide_Type (Left) + Wide_Type (Right);
which would simplify your code a bit. Or just write one expression:
return Discrete_Type (
Wide_Type'Min (Wide_Type (Discrete_Type'Last),
Wide_Type'Max (Wide_Type (Discrete_Type'First),
Wide_Type (Left) + Wide_Type (Right))));
That assumes that the formal Wide_Type is defined as an integer type,
not just as any discrete type.
HTH,
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Saturation arithmetic woes.
2009-07-29 19:14 ` Niklas Holsti
@ 2009-07-29 19:39 ` xorque
2009-07-30 9:09 ` Jean-Pierre Rosen
1 sibling, 0 replies; 7+ messages in thread
From: xorque @ 2009-07-29 19:39 UTC (permalink / raw)
Unfortunate how dangerous this stuff is, really.
Thanks, all.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Saturation arithmetic woes.
2009-07-29 19:14 ` Niklas Holsti
2009-07-29 19:39 ` xorque
@ 2009-07-30 9:09 ` Jean-Pierre Rosen
2009-07-30 11:51 ` Martin
1 sibling, 1 reply; 7+ messages in thread
From: Jean-Pierre Rosen @ 2009-07-30 9:09 UTC (permalink / raw)
Niklas Holsti a �crit :
>> package body Saturation is
>>
>> function "+"
>> (Left : Saturated_Type;
>> Right : Saturated_Type) return Saturated_Type
>> is
>> Temp_Left : constant Discrete_Type := Discrete_Type (Left);
>> Temp_Right : constant Discrete_Type := Discrete_Type (Right);
>> begin
>> if Temp_Left + Temp_Right > Discrete_Type'Last then
>
> Depending on the actual type associated with Discrete_Type (and assuming
> you use the predefined "+" for that type), you risk getting an overflow
> on Temp_Left + Temp_Right. If you have overflow checks disabled (as Gnat
> has by default) the sum may "wrap around" and seem to be less than
> Discrete_Type'Last, giving you the wrong result. If you have overflow
> checks enabled, you get a Constraint_Error instead of
> Discrete_Type'Last. Ditto for underflow and Discrete_Type'First.
>
But of course, the simplest way to check is to write:
if Temp_Left > Discrete_Type'Last - Temp_Right then
No overflow, ever! Of course, you need a "-" operator, and I assume it
is consistent with "+"...
--
---------------------------------------------------------
J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Saturation arithmetic woes.
2009-07-30 9:09 ` Jean-Pierre Rosen
@ 2009-07-30 11:51 ` Martin
0 siblings, 0 replies; 7+ messages in thread
From: Martin @ 2009-07-30 11:51 UTC (permalink / raw)
On Jul 30, 10:09 am, Jean-Pierre Rosen <ro...@adalog.fr> wrote:
> Niklas Holsti a écrit :
>
> >> package body Saturation is
>
> >> function "+"
> >> (Left : Saturated_Type;
> >> Right : Saturated_Type) return Saturated_Type
> >> is
> >> Temp_Left : constant Discrete_Type := Discrete_Type (Left);
> >> Temp_Right : constant Discrete_Type := Discrete_Type (Right);
> >> begin
> >> if Temp_Left + Temp_Right > Discrete_Type'Last then
>
> > Depending on the actual type associated with Discrete_Type (and assuming
> > you use the predefined "+" for that type), you risk getting an overflow
> > on Temp_Left + Temp_Right. If you have overflow checks disabled (as Gnat
> > has by default) the sum may "wrap around" and seem to be less than
> > Discrete_Type'Last, giving you the wrong result. If you have overflow
> > checks enabled, you get a Constraint_Error instead of
> > Discrete_Type'Last. Ditto for underflow and Discrete_Type'First.
>
> But of course, the simplest way to check is to write:
> if Temp_Left > Discrete_Type'Last - Temp_Right then
>
> No overflow, ever! Of course, you need a "-" operator, and I assume it
> is consistent with "+"...
> --
> ---------------------------------------------------------
> J-P. Rosen (ro...@adalog.fr)
> Visit Adalog's web site athttp://www.adalog.fr
Temp_Right = -1 ?
Cheers
-- Martin
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-07-30 11:51 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-29 17:03 Saturation arithmetic woes xorque
2009-07-29 17:13 ` Martin
2009-07-29 18:14 ` Jeffrey R. Carter
2009-07-29 19:14 ` Niklas Holsti
2009-07-29 19:39 ` xorque
2009-07-30 9:09 ` Jean-Pierre Rosen
2009-07-30 11:51 ` Martin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox