From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,8af7fe40dc0a55ae X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!postnews.google.com!v13g2000yqm.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: Restarting Tread: Why isn't this program working with Unchecked_Converstion Date: Thu, 15 Jan 2009 18:27:35 -0800 (PST) Organization: http://groups.google.com Message-ID: <5df15a77-b654-41da-bea0-a799f4cb6230@v13g2000yqm.googlegroups.com> References: <83d19cd8-71ca-43c1-a3eb-05832290e565@r36g2000prf.googlegroups.com> <40239b21-b265-467f-9b27-5890fb2f4c67@w1g2000prm.googlegroups.com> NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: posting.google.com 1232072855 8371 127.0.0.1 (16 Jan 2009 02:27:35 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Fri, 16 Jan 2009 02:27:35 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: v13g2000yqm.googlegroups.com; posting-host=66.126.103.122; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.12) Gecko/20050922 Fedora/1.7.12-1.3.1,gzip(gfe),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:3369 Date: 2009-01-15T18:27:35-08:00 List-Id: On Jan 15, 12:53 pm, ChristopherL 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