Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Way to use Ada Mod function on floats?

663 views
Skip to first unread message

AAFe...@hotmail.com

unread,
Dec 1, 2006, 10:32:48 AM12/1/06
to
Hi guys,

I need to perform the mod operation on floats. Does anyone know of a
simple way to do this in Ada? It seems the mod function is only for
integers. I can probably multiply out the decimal places, and then
divide my answer back, but if there is a more simple way that saves
computations, I'd rather do that.

Thank you for any help you can provide!

AA

Jeffrey Creem

unread,
Dec 1, 2006, 11:37:19 AM12/1/06
to

Hmm. I can't think of anything predefined that makes it all that easy.

perhaps you should just pragma import the one from libc

Adam Beneschan

unread,
Dec 1, 2006, 12:21:07 PM12/1/06
to

The 'Remainder attribute may help---see A.5.3. T'Remainder(X,Y) [where
T is a floating-point type] will return a value in the range [-Y/2,
Y/2], which isn't exactly what you want, but I think you can just add Y
to the result if it's negative. I'm assuming that Y is positive here.

-- Adam

Chris Moore

unread,
Dec 1, 2006, 4:13:19 PM12/1/06
to

Something like this (I don't have a compiler near me atm) :

function Mod (N, M : Float) return Float is
I : Integer := Integer (N / M - 0.5);
begin
if I < 0 then I := I + 1; end if;
return N - Float (I) * M;
end Mod;

Chris

--
Sig pending!

Stephen Leake

unread,
Dec 2, 2006, 6:11:34 AM12/2/06
to
"AAFe...@hotmail.com" <AAFe...@hotmail.com> writes:

> Hi guys,
>
> I need to perform the mod operation on floats. Does anyone know of a
> simple way to do this in Ada? It seems the mod function is only for
> integers. I can probably multiply out the decimal places, and then
> divide my answer back, but if there is a more simple way that saves
> computations, I'd rather do that.

SAL (http://stephe-leake.org/ada/sal.html) has:

function Modulo (Dividend, Divisor : in Real_Type) return Real_Type
is
-- match names in Ada LRM 4.5.5

A : Real_Type renames Dividend;
B : Real_Type renames Divisor;
N : constant Integer := Integer (Real_Type'Floor (A / B));
begin
return A - B * Real_Type (N);
end Modulo;

--
-- Stephe

Gautier

unread,
Dec 2, 2006, 11:40:50 AM12/2/06
to
Stephen Leake:

> SAL (http://stephe-leake.org/ada/sal.html) has:
>
> function Modulo (Dividend, Divisor : in Real_Type) return Real_Type
> is
> -- match names in Ada LRM 4.5.5
>
> A : Real_Type renames Dividend;
> B : Real_Type renames Divisor;
> N : constant Integer := Integer (Real_Type'Floor (A / B));
> begin
> return A - B * Real_Type (N);
> end Modulo;

Out of curiosity, what is the need of converting Real_Type'Floor (A / B) to an
Integer and back to a Real_Type ?
______________________________________________________________
Gautier -- http://www.mysunrise.ch/users/gdm/index.htm
Ada programming -- http://www.mysunrise.ch/users/gdm/gsoft.htm

NB: For a direct answer, e-mail address on the Web site!

Simon Wright

unread,
Dec 2, 2006, 12:48:34 PM12/2/06
to
Gautier <gau...@fakeaddress.nil> writes:

> Stephen Leake:
>
>> SAL (http://stephe-leake.org/ada/sal.html) has:
>>
>> function Modulo (Dividend, Divisor : in Real_Type) return Real_Type
>> is
>> -- match names in Ada LRM 4.5.5
>>
>> A : Real_Type renames Dividend;
>> B : Real_Type renames Divisor;
>> N : constant Integer := Integer (Real_Type'Floor (A / B));
>> begin
>> return A - B * Real_Type (N);
>> end Modulo;
>
> Out of curiosity, what is the need of converting Real_Type'Floor (A /
> B) to an Integer and back to a Real_Type ?

Especially when it can overflow and give you a Constraint_Error.

Dmitry A. Kazakov

unread,
Dec 2, 2006, 1:21:43 PM12/2/06
to

Hmm, why is it converted to integer? I would stay all the way in
Real_Type'Base:

return Real_Type'Base
(Dividend - Divisor * Real_Type'Base'Floor (Dividend / Divisor));

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

Dmitry A. Kazakov

unread,
Dec 2, 2006, 1:24:31 PM12/2/06
to

Of course, a qualified expression meant, so Real_Type'Base' in the first
line.

Jeffrey R. Carter

unread,
Dec 2, 2006, 7:50:49 PM12/2/06
to
Simon Wright wrote:
> Gautier <gau...@fakeaddress.nil> writes:
>
>> Stephen Leake:
>>
>>> N : constant Integer := Integer (Real_Type'Floor (A / B));
>>
>> Out of curiosity, what is the need of converting Real_Type'Floor (A /
>> B) to an Integer and back to a Real_Type ?
>
> Especially when it can overflow and give you a Constraint_Error.

And why 'Floor? Wouldn't 'Truncation be better?

--
Jeff Carter
"Run away! Run away!"
Monty Python and the Holy Grail
58

Randy Brukardt

unread,
Dec 2, 2006, 8:05:41 PM12/2/06
to
"Gautier" <gau...@fakeaddress.nil> wrote in message
news:4571a...@news.bluewin.ch...

> Stephen Leake:
>
> > SAL (http://stephe-leake.org/ada/sal.html) has:
> >
> > function Modulo (Dividend, Divisor : in Real_Type) return Real_Type
> > is
> > -- match names in Ada LRM 4.5.5
> >
> > A : Real_Type renames Dividend;
> > B : Real_Type renames Divisor;
> > N : constant Integer := Integer (Real_Type'Floor (A / B));
> > begin
> > return A - B * Real_Type (N);
> > end Modulo;
>
> Out of curiosity, what is the need of converting Real_Type'Floor (A / B)
to an
> Integer and back to a Real_Type ?

He just wanted to get Constraint_Error sometimes (esp. on Janus/Ada, where
Integer is 16 bits!). ;-)

Randy.


Stephen Leake

unread,
Dec 3, 2006, 10:14:59 AM12/3/06
to
Gautier <gau...@fakeaddress.nil> writes:

> Stephen Leake:
>
>> SAL (http://stephe-leake.org/ada/sal.html) has:
>> function Modulo (Dividend, Divisor : in Real_Type) return
>> Real_Type
>> is
>> -- match names in Ada LRM 4.5.5
>> A : Real_Type renames Dividend;
>> B : Real_Type renames Divisor;
>> N : constant Integer := Integer (Real_Type'Floor (A / B));
>> begin
>> return A - B * Real_Type (N);
>> end Modulo;
>
> Out of curiosity, what is the need of converting Real_Type'Floor (A /
> B) to an Integer and back to a Real_Type ?

Since so many others claim to be able to read my mind, I almost feel
it is unnecessary to answer!

It is a mistake to convert to Integer; my tests for this pass when I
delete that.

This code was first written for Ada 83. Hmm; the Ada 95 LRM says
'Floor _did_ exist then (it is not listed as an extension to Ada 83),
but apparently I was unaware of it, or it didn't exist in the DEC Ada
compiler, or something. So I used 'round to Integer' instead:

function Modulo (Dividend, Divisor : in FLOAT_TYPE) return FLOAT_TYPE
is
-- match names in LRM 4.5.5

A : FLOAT_TYPE renames Dividend;
B : FLOAT_TYPE renames Divisor;
Quotient : FLOAT_TYPE := Dividend / Divisor;
N : INT_32_TYPE := INT_32_TYPE (Quotient - 0.5);
begin
return A - B * FLOAT_TYPE (N);
end Modulo;

Apparently when I converted to using 'Float, I did not fully think it
thru. Thanks for pointing this out.

It is always useful to expose code to review by experts :).

Using 'Truncation gives different sign results; 'Floor matches the
integer definition of "mod":

Mod (10.0, 5.0) : 0.00000
Mod (11.0, 5.0) : 1.00000
Mod (14.0, 5.0) : 4.00000
Mod (10.0, -5.0) : 0.00000
Mod (11.0, -5.0) : -4.00000
Mod (14.0, -5.0) : -1.00000
Mod (-10.0, 5.0) : 0.00000
Mod (-11.0, 5.0) : 4.00000
Mod (-14.0, 5.0) : 1.00000
Mod (-10.0, -5.0) : 0.00000
Mod (-11.0, -5.0) : -1.00000
Mod (-14.0, -5.0) : -4.00000
Mod (0.0, 2.0) : 0.00000

Perhaps 'Truncation would match "rem"? I haven't looked at it in
detail.

--
-- Stephe

Jeffrey R. Carter

unread,
Dec 3, 2006, 5:27:00 PM12/3/06
to
Stephen Leake wrote:
>
> Perhaps 'Truncation would match "rem"? I haven't looked at it in
> detail.

OK. Some of the suggestions have actually been for "rem" equivalents,
which may be why I was thinking along those lines. Ada is about the only
language that provides both, and many use a name like "mod" for
remainder functions.

So, why don't you call your function "mod"?

--
Jeff Carter
"No one is to stone anyone until I blow this whistle,
do you understand? Even--and I want to make this
absolutely clear--even if they do say, 'Jehovah.'"
Monty Python's Life of Brian
74

Stephen Leake

unread,
Dec 4, 2006, 6:31:00 AM12/4/06
to
"Jeffrey R. Carter" <spam.not...@acm.not.spam.org> writes:

> Stephen Leake wrote:
>> Perhaps 'Truncation would match "rem"? I haven't looked at it in
>> detail.
>
> OK. Some of the suggestions have actually been for "rem" equivalents,
> which may be why I was thinking along those lines. Ada is about the
> only language that provides both, and many use a name like "mod" for
> remainder functions.
>
> So, why don't you call your function "mod"?

It is renamed to that in the spec.

In the original implementation, the body was separate, to allow for
different implementations (in assembler) on different processors.
Separate bodies cannot have operator names. That turned out to be
unnecessary, but I kept the names.

I prefer non-operator names in bodies; it makes searching for things
easier.

--
-- Stephe

0 new messages