* Re: Another question about fixed point types.
2010-08-28 22:45 Another question about fixed point types Peter C. Chapin
@ 2010-08-29 6:32 ` Yannick Duchêne (Hibou57)
2010-08-29 11:23 ` Peter C. Chapin
2010-08-29 9:02 ` Phil Thornley
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-08-29 6:32 UTC (permalink / raw)
Le Sun, 29 Aug 2010 00:45:16 +0200, Peter C. Chapin <chapinp@acm.org> a
écrit:
> That range does not include zero. However, the
> code above compiles and runs fine using GNAT GPL 2010.
I have never used fixed point type in Ada (nor floats by the way, but will
do in the future for sound synthesis).
However, I had a look at the reference, and here is what it says which may
be relevant in your area:
ARM 2005 - 3.5.9 Fixed Point Types - says:
12{base range (of a fixed point type) [partial]} The base range (see
3.5)
of a fixed point type is symmetric around zero, except possibly for an
extra
negative value in some implementations.
If it is symmetric around zero, that should explain your observations, as
I would be very surprised if there would be provision for a hole
somewhere. If it is symmetric around zero, and there is no two disjoint
range, then this is include zero.
A tiny test program which would write first and last of the base type may
tell more.
Hint: note the “possibly for an extra negative value in some
implementations”, which may be important for you as you seems to require
deep understanding of what's going on.
> P.S. The code above is a simplification of the real code, but I believe
> it illustrates the question I have.
Yes, it seems it illustrates fine.
--
“Dual licensing is the Perl's way to disinfect the GNU General Public
Virus!” (anonymous)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Another question about fixed point types.
2010-08-29 6:32 ` Yannick Duchêne (Hibou57)
@ 2010-08-29 11:23 ` Peter C. Chapin
0 siblings, 0 replies; 13+ messages in thread
From: Peter C. Chapin @ 2010-08-29 11:23 UTC (permalink / raw)
On 2010-08-29 02:32, Yannick Duchêne (Hibou57) wrote:
> If it is symmetric around zero, that should explain your observations,
> as I would be very surprised if there would be provision for a hole
> somewhere. If it is symmetric around zero, and there is no two disjoint
> range, then this is include zero.
>
> A tiny test program which would write first and last of the base type
> may tell more.
You're right. Thanks for pointing that out. Here is the range of
Julian_Day'Base that I obtained using a test program:
-9007199254740992.000 .. 9007199254740991.999
So my understanding was that for integral types the compiler is allowed
to allocate only the number of bits necessary to hold the range. For
example:
type Example_Type is range 1000 .. 1001;
The compiler is permitted (not required) to represent objects of type
Example_Type using only a single bit. But I guess this is a separate
issue. The base type, in which computations are done, might be wide even
if the compiler chooses to store the objects in a much small space.
So in my case as Phil explained computations on Julian Day are being
done, most likely, with a 64 bit type. Yet despite that, storage could
(perhaps) be using a smaller space since 64 bits is not needed to
represent the full range of Julian_Day at my specified resolution.
I understand that these details are compiler specific. However, it does
seem like my code, at least, should be portable in its effect.
Peter
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Another question about fixed point types.
2010-08-28 22:45 Another question about fixed point types Peter C. Chapin
2010-08-29 6:32 ` Yannick Duchêne (Hibou57)
@ 2010-08-29 9:02 ` Phil Thornley
2010-08-29 11:29 ` Peter C. Chapin
2010-08-29 10:24 ` Simon Wright
2010-08-29 14:02 ` Stephen Leake
3 siblings, 1 reply; 13+ messages in thread
From: Phil Thornley @ 2010-08-29 9:02 UTC (permalink / raw)
On 28 Aug, 23:45, "Peter C. Chapin" <chap...@acm.org> wrote:
> Hello!
>
> Consider this type definition:
>
> type Julian_Day is delta 0.001 range 2_415_385.5 .. 2_489_665.0;
>
> Now consider this function that is intended to return the (approximate)
> interval between two Julian days in seconds:
>
> function Interval_Between
> (Left : Julian_Day; Right : Julian_Day) return Duration is
> Result : Duration;
> begin
> if Left > Right then
> Result := 86_400.0 * (Left - Right);
> else
> Result := 86_400.0 * (Right - Left);
> end if;
> return Result;
> end Interval_Between;
>
> The difference 'Left - Right' is definitely not in the range of
> Julian_Day. It is likely to be a small value and could even be zero. I
> understand that the computation of 'Left - Right' will be done in
> Julian_Day's base type but I'm unclear what that means to me.
>
> It is my understanding that the compiler is allowed to choose a base
> type that can only deal with the small-ish range of values between the
> limits of Julian_Day. That range does not include zero. However, the
> code above compiles and runs fine using GNAT GPL 2010. My test program
> includes a case where Left and Right are the same so the difference is
> zero. Is this code reliable or am I just seeing the effect of GNAT's
> particular, implementation-specific choices?
As Yannick points out, the base type will be symettric around zero.
(That extra negative value is allowed so that 2's complement machines
don't have work to exclude it.)
With that definition, the largest value that 'Small is allowed to take
is 2**-10, and the upper bound is between 2**21 and 2**22, so the
minimum number of bits for the base type will be 33 (which may or may
not be significant to you).
Assuming that the compiler is allocating 64 bits for the type, it can
choose any 'Small such that the actual range of the base type includes
at least the specified range, so it could be anywhere between
2**-10, with a range -(2**53) .. (2**63 - 1)*2**-10
and
2**-41 with a range -(2**22) .. (2**63 - 1)*2**-41
(and if this is SPARK, there's no base type assertion for fixed point
types...)
Cheers,
Phil
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Another question about fixed point types.
2010-08-29 9:02 ` Phil Thornley
@ 2010-08-29 11:29 ` Peter C. Chapin
2010-08-29 12:31 ` Phil Thornley
0 siblings, 1 reply; 13+ messages in thread
From: Peter C. Chapin @ 2010-08-29 11:29 UTC (permalink / raw)
On 2010-08-29 05:02, Phil Thornley wrote:
> With that definition, the largest value that 'Small is allowed to take
> is 2**-10, and the upper bound is between 2**21 and 2**22, so the
> minimum number of bits for the base type will be 33 (which may or may
> not be significant to you).
Using 64 bit integers for computations isn't too scary if it is
necessary for handling my required precision. I'd prefer not to have to
store the values in 64 bits if I can avoid it. It sounds like I might
have to take a little more control over the representation of certain
numeric types than I might ideally like. It's still a little early to be
sure (meaning I'm not going to worry about it until performance
measurements indicate that it's actually a problem). That said, I do
want to at least understand the issues.
> (and if this is SPARK, there's no base type assertion for fixed point
> types...)
I hope this doesn't sound like a stupid question but what do you mean by
"base type assertion." Do you mean 'for Julian_Day'Base use ...'?
Peter
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Another question about fixed point types.
2010-08-29 11:29 ` Peter C. Chapin
@ 2010-08-29 12:31 ` Phil Thornley
2010-08-29 13:49 ` Jeffrey Carter
2010-08-29 14:20 ` Peter C. Chapin
0 siblings, 2 replies; 13+ messages in thread
From: Phil Thornley @ 2010-08-29 12:31 UTC (permalink / raw)
On 29 Aug, 12:29, "Peter C. Chapin" <chap...@acm.org> wrote:
> On 2010-08-29 05:02, Phil Thornley wrote:
[...]
> > (and if this is SPARK, there's no base type assertion for fixed point
> > types...)
>
> I hope this doesn't sound like a stupid question but what do you mean by
> "base type assertion." Do you mean 'for Julian_Day'Base use ...'?
Peter,
(sorry for causing some confusion)
I was referring to the SPARK annotation that tells the Examiner which
predefined type the compiler will use as the base type of a type
declaration - it's needed for overflow checks and looks like:
type An_Int is range -10_000 .. 10_000;
--# assert An_Int'Base is Short_Integer;
where the range for Short_Integer is defined in the SPARK
configuration file (which should contain copies of the declarations in
package Standard for your compiler).
See Section 3.3.2.3 of the Proof Manual in the GPL 2010 documentation.
These don't work for fixed point types are there aren't any fixed-
point types declared in Standard.
Cheers,
Phil
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Another question about fixed point types.
2010-08-29 12:31 ` Phil Thornley
@ 2010-08-29 13:49 ` Jeffrey Carter
2010-08-29 14:20 ` Peter C. Chapin
1 sibling, 0 replies; 13+ messages in thread
From: Jeffrey Carter @ 2010-08-29 13:49 UTC (permalink / raw)
On 08/29/2010 05:31 AM, Phil Thornley wrote:
>
> These don't work for fixed point types are there aren't any fixed-
> point types declared in Standard.
Duration.
--
Jeff Carter
"We call your door-opening request a silly thing."
Monty Python & the Holy Grail
17
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Another question about fixed point types.
2010-08-29 12:31 ` Phil Thornley
2010-08-29 13:49 ` Jeffrey Carter
@ 2010-08-29 14:20 ` Peter C. Chapin
2010-08-29 17:50 ` Phil Thornley
1 sibling, 1 reply; 13+ messages in thread
From: Peter C. Chapin @ 2010-08-29 14:20 UTC (permalink / raw)
On 2010-08-29 08:31, Phil Thornley wrote:
> I was referring to the SPARK annotation that tells the Examiner which
> predefined type the compiler will use as the base type of a type
> declaration - it's needed for overflow checks and looks like:
>
> type An_Int is range -10_000 .. 10_000;
> --# assert An_Int'Base is Short_Integer;
>
> where the range for Short_Integer is defined in the SPARK
> configuration file
I see, okay. So am I right in saying that one should provide one of
these annotations for every scalar type definition in a SPARK program?
I'm guessing that by doing so SPARK could prove more automatically since
it would have more information. On the other hand it then becomes my
responsibility to get the base type right.
Peter
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Another question about fixed point types.
2010-08-29 14:20 ` Peter C. Chapin
@ 2010-08-29 17:50 ` Phil Thornley
2010-08-29 22:03 ` Peter C. Chapin
2010-08-30 8:50 ` Mark Lorenzen
0 siblings, 2 replies; 13+ messages in thread
From: Phil Thornley @ 2010-08-29 17:50 UTC (permalink / raw)
On 29 Aug, 15:20, "Peter C. Chapin" <chap...@acm.org> wrote:
> On 2010-08-29 08:31, Phil Thornley wrote:
>
> > I was referring to the SPARK annotation that tells the Examiner which
> > predefined type the compiler will use as the base type of a type
> > declaration - it's needed for overflow checks and looks like:
>
> > type An_Int is range -10_000 .. 10_000;
> > --# assert An_Int'Base is Short_Integer;
>
> > where the range for Short_Integer is defined in the SPARK
> > configuration file
>
> I see, okay. So am I right in saying that one should provide one of
> these annotations for every scalar type definition in a SPARK program?
> I'm guessing that by doing so SPARK could prove more automatically since
> it would have more information. On the other hand it then becomes my
> responsibility to get the base type right.
It's all about completing the proofs of overflow checks - where the
Simplifier needs to know the range of the base type. Up to and
including version 8.1.1 of last year, it was optional whether to
include these checks when VCs were generated for run-time checks
(generated only if you used the -exp qualifier for the Examiner). But
in the recent 2010 version the overflow checks have become mandatory
and can't be turned off.
It's certainly a good idea to put them in - the coding standards of
last project I worked on required a base type assertion for every new
integer or floating point type declared.
You do have to get them right - OTOH it's always safe to use the
smallest possible range for the base type as it doesn't matter if you
prove the checks for a more restricted range.
For some compilers it's possible to check that the actual base type is
what you expected it to be.
Cheers,
Phil
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Another question about fixed point types.
2010-08-29 17:50 ` Phil Thornley
@ 2010-08-29 22:03 ` Peter C. Chapin
2010-08-30 8:50 ` Mark Lorenzen
1 sibling, 0 replies; 13+ messages in thread
From: Peter C. Chapin @ 2010-08-29 22:03 UTC (permalink / raw)
On 2010-08-29 13:50, Phil Thornley wrote:
> It's all about completing the proofs of overflow checks - where the
> Simplifier needs to know the range of the base type. Up to and
> including version 8.1.1 of last year, it was optional whether to
> include these checks when VCs were generated for run-time checks
> (generated only if you used the -exp qualifier for the Examiner). But
> in the recent 2010 version the overflow checks have become mandatory
> and can't be turned off.
Thanks, this is good to know.
Peter
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Another question about fixed point types.
2010-08-29 17:50 ` Phil Thornley
2010-08-29 22:03 ` Peter C. Chapin
@ 2010-08-30 8:50 ` Mark Lorenzen
1 sibling, 0 replies; 13+ messages in thread
From: Mark Lorenzen @ 2010-08-30 8:50 UTC (permalink / raw)
On 29 Aug., 19:50, Phil Thornley <phil.jpthorn...@gmail.com> wrote:
>
> You do have to get them right - OTOH it's always safe to use the
> smallest possible range for the base type as it doesn't matter if you
> prove the checks for a more restricted range.
>
It would be handy if the Examiner would insert safe default base type
assertions just as it inserts default loop invariants.
- Mark L
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Another question about fixed point types.
2010-08-28 22:45 Another question about fixed point types Peter C. Chapin
2010-08-29 6:32 ` Yannick Duchêne (Hibou57)
2010-08-29 9:02 ` Phil Thornley
@ 2010-08-29 10:24 ` Simon Wright
2010-08-29 14:02 ` Stephen Leake
3 siblings, 0 replies; 13+ messages in thread
From: Simon Wright @ 2010-08-29 10:24 UTC (permalink / raw)
"Peter C. Chapin" <chapinp@acm.org> writes:
> Consider this type definition:
>
> type Julian_Day is delta 0.001 range 2_415_385.5 .. 2_489_665.0;
I'd add
for Julian_Day'Small use 0.001;
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Another question about fixed point types.
2010-08-28 22:45 Another question about fixed point types Peter C. Chapin
` (2 preceding siblings ...)
2010-08-29 10:24 ` Simon Wright
@ 2010-08-29 14:02 ` Stephen Leake
3 siblings, 0 replies; 13+ messages in thread
From: Stephen Leake @ 2010-08-29 14:02 UTC (permalink / raw)
"Peter C. Chapin" <chapinp@acm.org> writes:
> type Julian_Day is delta 0.001 range 2_415_385.5 .. 2_489_665.0;
>
> Now consider this function that is intended to return the (approximate)
> interval between two Julian days in seconds:
>
> function Interval_Between
> (Left : Julian_Day; Right : Julian_Day) return Duration is
> Result : Duration;
> begin
> if Left > Right then
> Result := 86_400.0 * (Left - Right);
> else
> Result := 86_400.0 * (Right - Left);
> end if;
> return Result;
> end Interval_Between;
>
> The difference 'Left - Right' is definitely not in the range of
> Julian_Day. It is likely to be a small value and could even be zero.
Or negative.
> I understand that the computation of 'Left - Right' will be done in
> Julian_Day's base type but I'm unclear what that means to me.
This is no different than using Integer_16 to evaluate 30_000 * 30_000;
if an intermediate value is outside the base type range, you get
Constraint_Error at runtime.
> It is my understanding that the compiler is allowed to choose a base
> type that can only deal with the small-ish range of values between the
> limits of Julian_Day. That range does not include zero. However, the
> code above compiles and runs fine using GNAT GPL 2010. My test program
> includes a case where Left and Right are the same so the difference is
> zero. Is this code reliable or am I just seeing the effect of GNAT's
> particular, implementation-specific choices?
It is harder to guess what the compiler will choose as the base type
for fixed_point than for integer, but it's still just a guess; the base
type for Integer_16 could be 32 bits.
If you want to ensure that intermediate values are safe, you need to
widen the range of the type declaration, so the compiler is forced to
choose a safe base type. You could then use a subtype to provide a
restricted range:
type Safe_Julian_Day is delta 0.001 range -2_489_665.0 .. 2_489_665.0;
subtype Julian_Day is Safe_Julian_Day range 2_415_385.5 .. 2_489_665.0;
--
-- Stephe
^ permalink raw reply [flat|nested] 13+ messages in thread