comp.lang.ada
 help / color / mirror / Atom feed
* Positive Floating Range?
@ 2001-04-21  3:21 Dr Nancy's Sweetie
  2001-04-21  7:25 ` tmoran
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Dr Nancy's Sweetie @ 2001-04-21  3:21 UTC (permalink / raw)



I looked in a few books and at some FAQs, but maybe I just wasn't
looking in the right place.

I want to specify a subtype for floating point numbers which will
only allow positive numbers to be entered.  I can do something like
this:
      subtype Foo is Float range 0.0..Float'Last;

and then test for zero myself whenever somebody enters a number,
but that feels an awful lot like a kludge.

I tried float'first, but it turned out to be a negative number of
large magnitude, not a positive number of small magnitude.  Trying
this:
	Put(Float'succ(0.0));
gave me:
	0.00000E+00

This test:

	if Float'Succ(0.0) = 0.0 then
		Put("They're equal!");
	else
		Put("Not equal!");
	end if;

said "Not equal!", but then why didn't the previous "put" give me
something like "1.1E-52"?

So it looks like I get what I want with:

      subtype Foo is Float range Float'Succ(0.0)..Float'Last;

When I tried that, and typed in "0.0" for a "Get(fooVar);", it
didn't give a constraint error.  So there's apparently something
I can't see going on here.


Also, while I can get a Float, the compiler claims that there's no
such thing as a "Double".  At first I figured maybe Ada used the
double all the time (like Perl does), but Float'Machine_Radix is 2,
and Float'Machine_Mantissa is 24; that's single precision on this
machine.  How do I get what C calls `double'?

I found a reference to things like this:

	type foo is delta 0.000001 digits 20;

But it's not clear what happens if I specify something which is too
precise (or too many digits) for the machine's natural double-word size.
Does it truncate, or build its own floating type and then do the work in
software?  The former seems sorta anti-Adaish (just throwing out your
information), and the latter could be time consuming.  I just want it to
use the machine's natural double word size.  Is there some way to do that?


Since these are pretty basic questions, it may be best to e-mail you
responses directly to me and I'll summarise in a few days.  Thanks!


Darren F Provine ! kilroy@copland.rowan.edu ! http://www.rowan.edu/~kilroy
"The obvious mathematical breakthrough would be development of an easy
 way to factor large prime numbers." 
    -- Bill Gates, _The Road Ahead_, Viking Penguin (1995), page 265



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

* Re: Positive Floating Range?
  2001-04-21  3:21 Positive Floating Range? Dr Nancy's Sweetie
@ 2001-04-21  7:25 ` tmoran
  2001-04-21 14:57 ` Samuel T. Harris
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: tmoran @ 2001-04-21  7:25 UTC (permalink / raw)


>Also, while I can get a Float, the compiler claims that there's no
>such thing as a "Double".  At first I figured maybe Ada used the
>double all the time (like Perl does), but Float'Machine_Radix is 2,
  Normally in Ada you are supposed to specify exactly what you want
type Rough is digits 3;
type Very_Precise is digits 11;

>But it's not clear what happens if I specify something which is too
>precise (or too many digits) for the machine's natural double-word size.
  LRM 3.5.7(7) says "A floating_point definition is illegal if the
implementation does not support a floating point type that satisfies
the requested decimal precision and range."

  You can be sloppy and use Float because LRM 3.5.7(12) says "There
is a predefined, unconstrained, floating point subtype named Float,
declared in the visible part of the package Standard."  But it's
*possible* Float is not as big as you want, since LRM3.5.7(14) says
merely "In an implementation that supports floating point types with
6 or more digits of precision, the requested decimal precision for
Float shall be at least 6."  But if you did happen to be on a machine
with, say, 4 digit Floats, then
  X : Float;
would be only 4 digits, and perhaps generate incorrect answers, while
  type Minimal_Float is digits 5;
  X : Minimal_Float;
would force the compiler to generate a "No can do" message at the
Minimal_Float declaration, thus warning you of the potential problem.

  You may be able to also use Long_Float since LRM 3.5.7(15) says
"If Long_Float is predefined for an implementation, then its requested
decimal precision shall be at least 11."

>        type foo is delta 0.000001 digits 20;
  That declares a decimal fixed point type, not a binary floating
point one.



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

* Re: Positive Floating Range?
  2001-04-21  3:21 Positive Floating Range? Dr Nancy's Sweetie
  2001-04-21  7:25 ` tmoran
@ 2001-04-21 14:57 ` Samuel T. Harris
  2001-04-22  1:14 ` Jeffrey Carter
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Samuel T. Harris @ 2001-04-21 14:57 UTC (permalink / raw)


Dr Nancy's Sweetie wrote:
> 
> So it looks like I get what I want with:
> 
>       subtype Foo is Float range Float'Succ(0.0)..Float'Last;
> 
> When I tried that, and typed in "0.0" for a "Get(fooVar);", it
> didn't give a constraint error.  So there's apparently something
> I can't see going on here.

Try entering just "0". I believe Ada 95 requires the simple
integer to be appropriate for input to real types.

If I remember correctly ...

Ada requires that the conversion of an integer type to a float
zero out all the decimal digits. A conversion of a short_float
to a long_float does NOT require zeroing out the extra digits.

Hopefully, by entering a 0, an internal conversion will
occur and assure that you get a 0.0 and all zero digits.


-- 
Samuel T. Harris, Principal Engineer
Raytheon, Aerospace Engineering Services
"If you can make it, We can fake it!"



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

* Re: Positive Floating Range?
  2001-04-21  3:21 Positive Floating Range? Dr Nancy's Sweetie
  2001-04-21  7:25 ` tmoran
  2001-04-21 14:57 ` Samuel T. Harris
@ 2001-04-22  1:14 ` Jeffrey Carter
  2001-04-23 14:13 ` Marin David Condic
  2001-05-01 20:40 ` Georg Bauhaus
  4 siblings, 0 replies; 6+ messages in thread
From: Jeffrey Carter @ 2001-04-22  1:14 UTC (permalink / raw)


Dr Nancy's Sweetie wrote:
> 
> I want to specify a subtype for floating point numbers which will
> only allow positive numbers to be entered.  I can do something like
> this:
>       subtype Foo is Float range 0.0..Float'Last;
> 
> and then test for zero myself whenever somebody enters a number,
> but that feels an awful lot like a kludge.

The PragmAda Reusable Components use

   subtype Positive_Real is Real range  Real'Model_Small ..
Real'Safe_Last;

You might find it useful to review the language-defined attributes in
the ARM.

> Also, while I can get a Float, the compiler claims that there's no
> such thing as a "Double".  At first I figured maybe Ada used the
> double all the time (like Perl does), but Float'Machine_Radix is 2,
> and Float'Machine_Mantissa is 24; that's single precision on this
> machine.  How do I get what C calls `double'?

Unlike most other languages, in which you use the numeric types the
language provides, in Ada you generally tell the compiler what your
application needs, and it creates the appropriate numeric type. There is
a predefined floating-point type named "Float" with a guaranteed
precision of at least 6 decimal digits (if that's possible on the
target). There may be other predefined floating-point types, but they're
not guaranteed to exist for all compilers, and so are not portable.

To portably get the maximum precision possible with any compiler (it may
differ from compiler to compiler, but will be the maximum available with
each compiler), you can use the constant System.Max_Digits:

with System;
...
   type Big is digits System.Max_Digits;

> 
> I found a reference to things like this:
> 
>         type foo is delta 0.000001 digits 20;

This is a fixed-point type, not a floating-point type. Floating-point
types are defined using

   type _name_ is digits _integer_number_ [range
_real_range_constraint_] ;

> 
> But it's not clear what happens if I specify something which is too
> precise (or too many digits) for the machine's natural double-word size.

If the compiler cannot comply with a type definition, you will get a
compiler error.

-- 
Jeff Carter
"I waggle my private parts at your aunties."
Monty Python & the Holy Grail



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

* Re: Positive Floating Range?
  2001-04-21  3:21 Positive Floating Range? Dr Nancy's Sweetie
                   ` (2 preceding siblings ...)
  2001-04-22  1:14 ` Jeffrey Carter
@ 2001-04-23 14:13 ` Marin David Condic
  2001-05-01 20:40 ` Georg Bauhaus
  4 siblings, 0 replies; 6+ messages in thread
From: Marin David Condic @ 2001-04-23 14:13 UTC (permalink / raw)


It seems that everyone missed your first question. AFAIK, there isn't going
to be any easy way of restricting a floating point subtype to only positive,
non-zero entities. At least not in a way that is always 100% portable and
takes full advantage of the machine.

You can pick some semi-arbitrary small number to be the lower bound:

subtype Foo is Float range 0.000001..Float'Last;

(At or about zero, things in floating point get pretty nasty anyway! :-)

You could also look into using attributes of floating point types to help
you out in picking the lower bound. (See ARM, A.5.3 for a full list.) Of
particular interest may be 'Model_Small, but I've never tried using
Float'Model_Small as a lower bound. See if:

subtype Foo is Float range Float'Model_Small..Float'Last;

gives you what you want. (And if it even compiles!)

You may still have problems getting this sort of thing to raise constraint
error because it is likely to be implementation dependent as to how
accurately "0.0" is going to get converted to a float by Text_IO and if this
is going to trigger a constraint error.

Hope this helps.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Dr Nancy's Sweetie" <kilroy@copland.rowan.edu> wrote in message
news:817E6.2056$DW1.94361@iad-read.news.verio.net...
>
> I looked in a few books and at some FAQs, but maybe I just wasn't
> looking in the right place.
>
> I want to specify a subtype for floating point numbers which will
> only allow positive numbers to be entered.  I can do something like
> this:
>       subtype Foo is Float range 0.0..Float'Last;
>
> and then test for zero myself whenever somebody enters a number,
> but that feels an awful lot like a kludge.
>
> I tried float'first, but it turned out to be a negative number of
> large magnitude, not a positive number of small magnitude.  Trying
> this:
> Put(Float'succ(0.0));
> gave me:
> 0.00000E+00
>
> This test:
>
> if Float'Succ(0.0) = 0.0 then
> Put("They're equal!");
> else
> Put("Not equal!");
> end if;
>
> said "Not equal!", but then why didn't the previous "put" give me
> something like "1.1E-52"?
>
> So it looks like I get what I want with:
>
>       subtype Foo is Float range Float'Succ(0.0)..Float'Last;
>
> When I tried that, and typed in "0.0" for a "Get(fooVar);", it
> didn't give a constraint error.  So there's apparently something
> I can't see going on here.
>
>
> Also, while I can get a Float, the compiler claims that there's no
> such thing as a "Double".  At first I figured maybe Ada used the
> double all the time (like Perl does), but Float'Machine_Radix is 2,
> and Float'Machine_Mantissa is 24; that's single precision on this
> machine.  How do I get what C calls `double'?
>
> I found a reference to things like this:
>
> type foo is delta 0.000001 digits 20;
>
> But it's not clear what happens if I specify something which is too
> precise (or too many digits) for the machine's natural double-word size.
> Does it truncate, or build its own floating type and then do the work in
> software?  The former seems sorta anti-Adaish (just throwing out your
> information), and the latter could be time consuming.  I just want it to
> use the machine's natural double word size.  Is there some way to do that?
>
>
> Since these are pretty basic questions, it may be best to e-mail you
> responses directly to me and I'll summarise in a few days.  Thanks!
>
>
> Darren F Provine ! kilroy@copland.rowan.edu ! http://www.rowan.edu/~kilroy
> "The obvious mathematical breakthrough would be development of an easy
>  way to factor large prime numbers."
>     -- Bill Gates, _The Road Ahead_, Viking Penguin (1995), page 265





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

* Re: Positive Floating Range?
  2001-04-21  3:21 Positive Floating Range? Dr Nancy's Sweetie
                   ` (3 preceding siblings ...)
  2001-04-23 14:13 ` Marin David Condic
@ 2001-05-01 20:40 ` Georg Bauhaus
  4 siblings, 0 replies; 6+ messages in thread
From: Georg Bauhaus @ 2001-05-01 20:40 UTC (permalink / raw)


Dr Nancy's Sweetie (kilroy@copland.rowan.edu) wrote:


: 	Put(Float'succ(0.0));
: gave me:
: 	0.00000E+00

: ...
: So it looks like I get what I want with:

:       subtype Foo is Float range Float'Succ(0.0)..Float'Last;

I've tried this:

with ada.text_IO; use Ada.Text_IO;
procedure floats is

  subtype Pos_Float is Float range Float'Succ(0.0) .. float'last;
  package pfloat is new Ada.text_IO.Float_IO(pos_float);
  f: pos_float;

begin
   pfloat.put(Pos_Float'First); new_line;
   pfloat.get(f);
end floats;

teppich:~$ ./floats
 1.40130E-45
0.0

raised ADA.IO_EXCEPTIONS.DATA_ERROR : a-tiflio.adb:70 instantiated at floats.adb:5
teppich:~$

Hm... That's all of my 2c.

There has been some talk about one compiler using
80 hardware bits where available, so you should at
least get long floats. Nothing in the compiler docs?


Georg



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

end of thread, other threads:[~2001-05-01 20:40 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-04-21  3:21 Positive Floating Range? Dr Nancy's Sweetie
2001-04-21  7:25 ` tmoran
2001-04-21 14:57 ` Samuel T. Harris
2001-04-22  1:14 ` Jeffrey Carter
2001-04-23 14:13 ` Marin David Condic
2001-05-01 20:40 ` Georg Bauhaus

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