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.3 required=5.0 tests=BAYES_00,FREEMAIL_FROM, INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,937e32e44ab82465 X-Google-Attributes: gid103376,public From: Andreas Subject: Type conversion / computing problem Date: 2000/02/17 Message-ID: <38AC2493.F30492E1@gmx.net>#1/1 X-Deja-AN: 586978779 Content-Transfer-Encoding: 7bit Organization: Regionales Rechenzentrum Erlangen, Germany X-Accept-Language: en Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 Newsgroups: comp.lang.ada Date: 2000-02-17T00:00:00+00:00 List-Id: Hi! I need advice on a nice problem with data type conversions in Ada95 with GNAT: I am writing an small interpreter for an assembly-like language whose entire data should be stored in memory as the amount of bytes needed for a particular Ada-type (e.g. 4 bytes for Integers, 8 bytes for Long_Floats) and each of those bytes should be separately addressable. A register for this assembler should be 8 bytes and the rightmost byte is the least significant one. A register (just an array variable of type RegType) has to be an intermediate variable that should allow converting any type A to any type B (so I don't have to write separate functions for each possible conversion). So the functionality should be this (e.g.): 4-byte-Integer (e.g. 5) --> Register, bytes 5-8, least significant right --> 8-byte-Integer (e.g. 5) or 4-byte-Integer (e.g. 5) --> Register, bytes 5-8, least significant right --> 2-byte-Integer (e.g. 5) (the --> denote conversions). Of course, the value of the integers should not change when converted to a larger type. When converted to a Ada type, only the amount of bytes required for this type should be considered in the Register, thus (perhaps) changing the value (e.g. use the rightmost 2 bytes of the register for a Short_Integer). Currently I am using the following code for splitting/converting the Integer types into the array of bytes (register) and back (only functions for Standard.Integer given, for other Integers same algorithm): type Byte is mod 256; -- an unsigned byte type RegType is array (1..8) of Byte; -- register type BitIndexType is mod 8; -- for converting purposes -- This function converts data type Integer into an array of Byte's function RAS_Integer2Reg (IntValue: in Integer) return RegType is TempReg: RegType:= (others => 0); -- initialize with 0 BitIndex: BitIndexType := 0; ByteIndex: Integer := 8; -- least significant byte right in register Remainder: Integer; LocalIntValue: Integer; begin LocalIntValue := IntValue; while LocalIntValue /= 0 loop Remainder := LocalIntValue mod 2; LocalIntValue := LocalIntValue / 2; TempReg(ByteIndex) := TempReg(ByteIndex) + Byte(Remainder * 2**Integer(BitIndex)); if BitIndex = 7 then ByteIndex := ByteIndex - 1; -- switch to next byte end if; BitIndex := BitIndex + 1; end loop; return TempReg; end RAS_Integer2Reg; -- This function converts the array of Byte's into an Integer value function RAS_Reg2Integer (RegValue: in RegType) return Integer is TempInt: Integer := 0; BitIndex: Integer := 0; -- this time no mod type! begin for ByteIndex in reverse 5..8 loop -- Integer is only 4 bytes out of the -- 8 in RegType TempInt := TempInt + Integer(RegValue(ByteIndex)) * 2**BitIndex; BitIndex := BitIndex + 8; end loop; return TempInt; end RAS_Reg2Integer; Now, the problem is that these functions work perfectly only for positive Integers (I guess because of the unsigned Byte), not for negative values. Unfortunately, I cannot change the types Byte and RegType since they are required. How can I use the same data types for processing negative values without defining a signed byte like "type Byte is Integer range -128..127" (and I don't even think this would help)??? Furthermore it's required for an associated debugger that the entire register should be displayed as an 8-byte-Integer (I use Long_Long_Integer, but have already also tried a self-defined 64-bit-type for this). So if you do the conversion: 4-byte-Integer (Standard.Integer) --> RegType --> 8-byte-Integer (Long_Long_Int) the original value should of course be the same in 8-byte-Integer. This as well, when using the algorithms above, works only for positive values. For this example, I already tried defining a 8-Byte-array, doing an Unchecked_Conversion and changing the byte order "manually" (of course by program ;-)). But when I do this, Unchecked_Conversion seems to fill the byte array from left to right, not as required, from right to left, thus changing the original value. And the problem with negative values still persists. I would greatly appreciate any hints on how I can solve this problem of storing negative (Integer) values in an array of unsigned bytes with least significant byte right. (Yes, I'm looking for a rather uncomplicated solution, not writing a long algorithm with distinction between positive and negative values :-), but I would also be very happy about such a longer solution). Thanks in advance! Andreas P.S. Could you please send the reply via e-mail, too?! :-)