comp.lang.ada
 help / color / mirror / Atom feed
From: Adam Beneschan <adam@irvine.com>
Subject: Re: Restarting Tread: Why isn't this program working with Unchecked_Converstion
Date: Thu, 15 Jan 2009 18:27:35 -0800 (PST)
Date: 2009-01-15T18:27:35-08:00	[thread overview]
Message-ID: <5df15a77-b654-41da-bea0-a799f4cb6230@v13g2000yqm.googlegroups.com> (raw)
In-Reply-To: 40239b21-b265-467f-9b27-5890fb2f4c67@w1g2000prm.googlegroups.com

On Jan 15, 12:53 pm, ChristopherL <clusard...@aol.com> wrote:
> I'm restarting the tread [How to put 200 into an integer sub-type of
> 16 bits (code included)] with a new subject because the last was too
> long!
>
> How can I be getting the below error message with
> "Unchecked_Conversion".
>
> Isn't Unchecked_conversion just suppose to copy bits?
>
> I want to copy bits from an Ada float to a user defined short integer
> maintaining the same bit representation.
>
> Arg:Float;  -- From this with a value of 200
> subtype Short_integer is Integer range -(2 ** 7) .. ((2 ** 7) - 1 );
> Result2: Short_integer; --to this, and I want to round Arg
>
> These 3 definitions of Arg and Result2 can not chanage.
>
> Arg will never be negative or greater than 200/201.
>
> Chris L.
>
> with Unchecked_Conversion;
>
> procedure test is
>   subtype Short_integer1 is Natural range 0.. ((2 ** 10) - 1);
>   subtype Short_integer2 is Integer range -(2 ** 7)..((2 ** 7) - 1);
>
>   subtype A_Float is Float;
>
>   subtype A_Natural is Natural range 0..((2 ** 8) - 1);
>   -- The next line of code (if used) gives compilation error message:
>   -- A_NATURAL does not denote a first subtype
>   -- for A_Natural'Size use Short_integer1'Size;
>
>   Size_Of_Float : integer := Float'Size;      --32 bits long
>
>   Size_Of_short_integer: integer := Short_integer1'Size;--10 bits
> long
>   Size_Of_short_int: integer := Short_integer2'Size;--10 bits long
>
>   Size_Of_Natural: integer := A_Natural'Size;       --8 bits long
>
>   Arg     : A_Float;
>   Result2 : Short_integer2;
>   Result1 : Short_integer1;
>
>   function Get_Bits is new Unchecked_Conversion (Source =>
>     Short_integer1, Target => Short_integer2);
>
> Begin
>
> Arg := 200.0;
>
> Result1 := Short_integer1(Arg + 0.5);  -- Result1 becomes 201
> Result2 := Get_Bits (Result1);

OK, I think I can help, but before that I want to be clear on
something.
Result2's subtype is defined with the range -128 .. 127, so Result2
will never have the value 200.  It might have the same bit pattern as
the number 200, but the actual value will be -56.  If you used an
instance of Text_IO.Integer_IO to print out Result2, the output would
have "-56" in it.  If that's not the result you want, then there's
still a lot of confusion going on that we need to clear up first.  But
if you want help in getting things so that Result2 will be -56, then
we can work on that.

The problem here is that in the Ada definition of assignment, the
value on the right side is converted to the subtype of the result, and
that conversion could result in CONSTRAINT_ERROR.  For some reason,
your compiler has decided that Short_Integer2 is 10 bits.  The
Unchecked_Conversion is converting a 10-bit integer to a 10-bit
integer, which basically means it doesn't do anything (just copying
the bits).  Then, the code has a 10-bit integer whose value is 200;
then it checks the value against the bounds of the range, -128..127,
and decides that the value is out of range.  Not all compilers would
behave this way.  Many compilers would notice that, since the result
of Get_Bits has subtype Short_Integer2 and the variable Result2 has
the same subtype Short_Integer2, no actual checking is necessary
(assuming the values are valid).  Your compiler appears to do the
check anyway.

I think you'll have to force the compiler to work with 8-bit types
instead of 10-bit types.  Since you can't put a 'Size clause on a
subtype of Integer, you'll need to declare new types:

   type Short_Integer1 is range 0 .. (2**8)-1;   --not (2**10)-1
   for Short_Integer1'Size use 8;

   type Short_Integer2 is range -(2**7) .. (2**7)-1;
   for Short_Integer2'Size use 8;

Or, if Short_Integer2 *has* to be a subtype, then declare a new type
with a different name, force its size to be 8, and do a type
conversion from that new type to Short_Integer2 afterwards.

If that still doesn't work, perhaps because your compiler doesn't know
how to avoid looking at the leftover 2 bits, you may have to do
something inelegant:

   if Result1 >= 128
     then Result2 := Result1 - 256
     else Result2 := Result1;
   end if;

By the way, you probably don't want to add 0.5 in this code:

  Result1 := Short_integer1(Arg + 0.5);  -- Result1 becomes 201

In some languages, when you convert a real to an integer, the language
truncates to the next lower integer, so the way you do rounding is to
add 0.5 and then do the conversion.  In Ada, though, converting a real
to an integer does the rounding.  So adding your own 0.5 is wrong and
will give the wrong results.

  Result1 := Short_Integer1 (Arg);

is I think what you want.

I hope this helps.

                                 -- Adam



  parent reply	other threads:[~2009-01-16  2:27 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <83d19cd8-71ca-43c1-a3eb-05832290e565@r36g2000prf.googlegroups.com>
2009-01-15 21:22 ` Restarting Tread: Why isn't this program working with Unchecked_Converstion Jeffrey R. Carter
     [not found]   ` <37daf0e6-39b8-4820-a7fc-b6c5decf1ed8@q19g2000yqi.googlegroups.com>
2009-01-16  0:22     ` Jeffrey R. Carter
2009-01-16  1:37 ` Restarting Tread: Why isn't this program working with anon
     [not found] ` <40239b21-b265-467f-9b27-5890fb2f4c67@w1g2000prm.googlegroups.com>
2009-01-16  2:27   ` Adam Beneschan [this message]
     [not found]     ` <9069fcf7-4257-4439-ad4a-8d7c8c17f5cf@v5g2000pre.googlegroups.com>
2009-01-16 15:11       ` Restarting Tread: Why isn't this program working with Unchecked_Converstion Ludovic Brenta
2009-01-16 16:23         ` Martin
     [not found]         ` <70172b19-360c-4eba-815c-ede747c3bcdf@w39g2000prb.googlegroups.com>
2009-01-16 17:24           ` Ludovic Brenta
2009-01-16 17:26           ` Martin
2009-01-16 17:34           ` Georg Bauhaus
2009-01-16 12:18 ` Stuart
2009-01-16 23:14   ` sjw
2009-01-15 21:24 Martin
     [not found] ` <a8ef6226-db87-4c4c-b38e-9dbc77374f4c@t11g2000yqg.googlegroups.com>
2009-01-16  0:45   ` tmoran
2009-01-16  8:02   ` Martin
replies disabled

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