comp.lang.ada
 help / color / mirror / Atom feed
* Type conversion / computing problem
@ 2000-02-17  0:00 Andreas
  0 siblings, 0 replies; 4+ messages in thread
From: Andreas @ 2000-02-17  0:00 UTC (permalink / raw)


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?! :-)




^ permalink raw reply	[flat|nested] 4+ messages in thread
* Type conversion / computing problem
@ 2000-02-17  0:00 Andreas
  2000-02-17  0:00 ` Robert A Duff
  0 siblings, 1 reply; 4+ messages in thread
From: Andreas @ 2000-02-17  0:00 UTC (permalink / raw)


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?! :-)




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

end of thread, other threads:[~2000-02-22  0:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-02-17  0:00 Type conversion / computing problem Andreas
  -- strict thread matches above, loose matches on Subject: below --
2000-02-17  0:00 Andreas
2000-02-17  0:00 ` Robert A Duff
2000-02-22  0:00   ` Oliver Kellogg

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