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-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,ca7e14ee1b312f90 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-04-27 13:27:22 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!cyclone.bc.net!sjc70.webusenet.com!news.webusenet.com!pc01.webusenet.com!fe07.atl2.webusenet.com.POSTED!not-for-mail From: "David C. Hoos" Newsgroups: comp.lang.ada References: Subject: Re: Minimum Record Size? LONG MIME-Version: 1.0 Content-Type: text/plain; charset="Windows-1252" Content-Transfer-Encoding: 7bit X-Newsreader: Microsoft Outlook Express 6.00.2800.1106 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106 Message-ID: <4VWqa.39167$b9.13645@fe07.atl2.webusenet.com> X-Complaints-To: abuse@usenetserver.com X-Abuse-Info: Please be sure to forward a copy of ALL headers X-Abuse-Info: Otherwise we will be unable to process your complaint properly. NNTP-Posting-Date: Sun, 27 Apr 2003 16:17:04 EDT Date: Sun, 27 Apr 2003 15:25:33 -0500 Xref: archiver1.google.com comp.lang.ada:36661 Date: 2003-04-27T15:25:33-05:00 List-Id: I haven't communicated my point very well. The slice approach is not endianness-independent. The arithmetic approach given by Tom Moran which was an improvement on my original submission is endianness-independent (as was my original submission). The point is that merely re-ordering the parameters to your procedure will not work on a big-endian machine without re-coding the procedure itself. The bit orders need to be reversed, as well. "Steve" wrote in message news:yDRqa.638235$3D1.352789@sccrnsc01... > If I add the function: > function To_Eight_Bits_String( value : Eight_Bits_Type ) return String is > use Ada.Strings; > use Ada.Strings.Fixed; > temp_string : String( 1 .. 32 ); > result : String( 1 .. 8 ); > first : Positive; > last : Positive; > begin > Eight_Bits_Io.Put( temp_String, value, 2 ); > first := Index( temp_string, "#" ) + 1; > last := Index( temp_String, "#", Backward ) - 1; > Move( Source => temp_string( first .. last ), > Target => result, > Drop => left, > Justify => right, > Pad => '0' ); > return result; > end To_Eight_Bits_String; > > And the modify the main to read: > > for idx in 0 .. 23 loop > sb1 := 0; > sb2 := 0; > sb3 := 0; > sb4 := 0; > case idx is > when 0 .. 5 => > sb1 := 2 ** idx; > when 6 .. 11 => > sb2 := 2 ** (idx - 6); > when 12 .. 17 => > sb3 := 2 ** (idx - 12); > when 18 .. 23 => > sb4 := 2 ** (idx - 18); > end case; > Conv_4x6_to_8x3( sb1, sb2, sb3, sb4, eb1, eb2, eb3 ); > Ada.Text_Io.Put( To_Eight_Bits_String( eb3 ) & " " ); > Ada.Text_Io.Put( To_Eight_Bits_String( eb2 ) & " " ); > Ada.Text_Io.Put_Line( To_Eight_Bits_String( eb1 ) ); > end loop; > > I get the result: > 00000000 00000000 00000001 > 00000000 00000000 00000010 > 00000000 00000000 00000100 > 00000000 00000000 00001000 > 00000000 00000000 00010000 > 00000000 00000000 00100000 > 00000000 00000000 01000000 > 00000000 00000000 10000000 > 00000000 00000001 00000000 > 00000000 00000010 00000000 > 00000000 00000100 00000000 > 00000000 00001000 00000000 > 00000000 00010000 00000000 > 00000000 00100000 00000000 > 00000000 01000000 00000000 > 00000000 10000000 00000000 > 00000001 00000000 00000000 > 00000010 00000000 00000000 > 00000100 00000000 00000000 > 00001000 00000000 00000000 > 00010000 00000000 00000000 > 00100000 00000000 00000000 > 01000000 00000000 00000000 > 10000000 00000000 00000000 > > Which is what I expect. If a different ordering of the combination > of 3 six bit values to 8 bit values is desired, the function arguments > may be re-ordered. > > Steve > (The Duck) > > "David C. Hoos" wrote in message > news:NzPqa.24413$C%4.24334@fe10.atl2.webusenet.com... > > The problem with this approach is that it gives incorrect results. > > > > If you put in the original poster's input values, you get the > > same incorrect results that he did. > > > > Testing with four inputs having only one bit set is not really > > "tested." > > > > "Steve" wrote in message > > news:UVlqa.620033$3D1.340565@sccrnsc01... > > > > > > Here's an approach taking advantage of using "Slices" of arrays (tested > > > w/Gnat3.15p-nt): > > > > > > with Ada.Text_Io; > > > with Ada.Unchecked_Conversion; > > > > > > procedure Shift6to8 is > > > > > > type Six_Bits_Type is mod 2**6; > > > for Six_Bits_Type'Size use 6; > > > > > > type Eight_Bits_Type is mod 2**8; > > > for Eight_Bits_Type'Size use 8; > > > > > > package Eight_Bits_Io is > > > new Ada.Text_Io.Modular_Io( Eight_Bits_Type ); > > > > > > procedure Conv_4x6_to_8x3( in1, in2, in3, in4 : Six_Bits_Type; > > > out1, out2, out3 : out Eight_Bits_Type ) > is > > > type Bit_Array_Type is array( positive range <> ) of Boolean; > > > pragma pack( Bit_Array_Type ); > > > > > > subtype Six_Bits_Array_Type is Bit_Array_Type( 1 .. 6 ); > > > subtype Eight_Bits_Array_Type is Bit_Array_Type( 1 .. 8 ); > > > > > > function Conv is > > > new Ada.Unchecked_Conversion( Six_Bits_Type, > Six_Bits_Array_Type ); > > > function Conv is > > > new Ada.Unchecked_Conversion( Eight_Bits_Array_Type, > > > Eight_Bits_Type ); > > > > > > combined : Bit_Array_Type := Conv( in1 ) & Conv( in2 ) & Conv( in3 ) > & > > > Conv( in4 ); > > > begin > > > out1 := Conv( combined( 1 .. 8 ) ); > > > out2 := Conv( combined( 9 .. 16 ) ); > > > out3 := Conv( combined( 17 .. 24 ) ); > > > end Conv_4x6_to_8x3; > > > > > > sb1, sb2, sb3, sb4 : Six_Bits_Type; > > > eb1, eb2, eb3 : Eight_Bits_Type; > > > > > > begin > > > sb1 := 1; > > > sb2 := 1; > > > sb3 := 1; > > > sb4 := 1; > > > Conv_4x6_to_8x3( sb1, sb2, sb3, sb4, eb1, eb2, eb3 ); > > > Eight_Bits_Io.Put( eb1, 4, 2 ); > > > Ada.Text_Io.New_Line; > > > Eight_Bits_Io.Put( eb2, 4, 2 ); > > > Ada.Text_Io.New_Line; > > > Eight_Bits_Io.Put( eb3, 4, 2 ); > > > Ada.Text_Io.New_Line; > > > end Shift6to8; > > > > > > > > > "Dr Nancy's Sweetie" wrote in message > > > news:Hrdqa.9680$io.307974@iad-read.news.verio.net... > > > > > > > > I'm working on a program which has to take four six-bit hunks of data > > > > and regroup them into three eight-bit hunks. My first pass looked > like > > > > this: > > > > > > > > Code_Value : String := > > > > > > > "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-"; > > > > Clear : Unbounded_String := To_Unbounded_String(""); > > > > > > > > Part_1 : Unsigned_32 := 0; > > > > Part_2 : Unsigned_32 := 0; > > > > Part_3 : Unsigned_32 := 0; > > > > Part_4 : Unsigned_32 := 0; > > > > > > > > Segment : Unsigned_32 := 0; > > > > > > > > Val_1 : Unsigned_32; > > > > Val_2 : Unsigned_32; > > > > Val_3 : Unsigned_32; > > > > > > > > (some more vars and such) > > > > > > > > while Spot <= Coded'Last loop > > > > -- take four six-bit hunks > > > > Part_1 := Unsigned_32(Index(Code_Value, Coded(Spot > > > ..Spot )) -1); > > > > Part_2 := Unsigned_32(Index(Code_Value, > > > Coded(Spot+1..Spot+1)) -1); > > > > Part_3 := Unsigned_32(Index(Code_Value, > > > Coded(Spot+2..Spot+2)) -1); > > > > Part_4 := Unsigned_32(Index(Code_Value, > > > Coded(Spot+3..Spot+3)) -1); > > > > > > > > -- assemble them into one segment > > > > Segment := (Shift_Left(Part_1, 18) and 16#fc0000#) or > > > > (Shift_Left(Part_2, 12) and 16#03f000#) or > > > > (Shift_Left(Part_3, 6) and 16#000fc0#) or > > > > (Shift_left(Part_4, 0) and 16#00003f#) ; > > > > > > > > -- split segment into three eight-bit hunks > > > > Val_1 := (Shift_Right(Segment and 16#ff0000#, 16)); > > > > Val_2 := (Shift_Right(Segment and 16#00ff00#, 8)); > > > > Val_3 := (Shift_Right(Segment and 16#0000ff#, 0)); > > > > > > > > -- (now do some more stuff) > > > > end loop; > > > > > > > > This worked, but it seemed a little klunky. Figuring there ought to > > > > be a better way, I tried an Unchecked_Conversion: > > > > > > > > type Six_Bits is mod 2**6; > > > > type Four_Sixes is array (0..3) of Six_Bits; > > > > type Four_Group is record > > > > Part : Four_Sixes; > > > > end record; > > > > for Four_Group'Size use 24; > > > > > > > > type Eight_Bits is mod 2**8; > > > > type Three_Eights is array (0..2) of Eight_Bits; > > > > type Three_Group is record > > > > Part : Three_Eights; > > > > end record; > > > > for Three_Group'Size use 24; > > > > > > > > But the compiler (gnat 3.13p) won't let me do this: it says: > > > > > > > > size for "Four_Group" too small, minimum allowed is 32 > > > > > > > > > > > > Well, I figure, maybe there's some array overhead that I didn't > account > > > > for. Except that it doesn't have any problem with the Three_Group > being > > > > 24 bits, and that's also an array. But anyway, as a test, I rewrote > it > > > > like this: > > > > > > > > type Six_Bits is mod 2**6; > > > > type Four_Sixes is array (0..3) of Six_Bits; > > > > type Four_Group is record > > > > Part1, Part2, Part3, Part4 : Six_Bits; > > > > end record; > > > > for Four_Group'Size use 24; > > > > > > > > type Eight_Bits is mod 2**8; > > > > type Three_Eights is array (0..2) of Eight_Bits; > > > > type Three_Group is record > > > > Part1, Part2, Part3 : Eight_Bits; > > > > end record; > > > > for Three_Group'Size use 24; > > > > > > > > > > > > It still won't let me do that: the minimum size for a Four_Group is > > > > still 32 bits. Okay, so I set the Four_Group'Size to 32. Now it > > > > quite reasonably complains that the sizes for my Unchecked_Conversion > > > > are different. > > > > > > > > My best guess at this point was that it insisted on using a full byte > > > > to represent the Six_Bits type, but when I put in: > > > > > > > > for Six_Bits'Size use 6; > > > > > > > > there was no complaint. But four six-bit things require 32 bits to > > > > store, even though three eight-bit things fits in 24. > > > > > > > > > > > > When I turn on debugging (Ada.Command_Line, Getopt, and a -D switch > > > > can save a lot of time), I discover that after the > Unchecked_Conversion, > > > > the three eight-bit elements have the exact same values as the first > > > > three six-bit elements. So my only guess now is that even though the > > > > six-bit things are six bits big, they're being byte-aligned. > > > > > > > > ANYWAY, I got to the point where I was throwing in things such as > > > > > > > > pragma Pack(Four_Sixes); > > > > for Four_Sixes'Size use 24; > > > > > > > > And it still doesn't make any difference. The four-element array of > > > > six bit objects is 24 bits without a complaint, but the record still > > > > has to be 32 bits. > > > > > > > > > > > > So that led me to one more try: dispense with the records, and just > > > > do an Unchecked_Conversion directly on the arrays. The compiler is > > > > happy with it, both array sizes are 24 bits, and the code runs without > > > > crashing. But the results make no sense. > > > > > > > > If I put in C3zY, which map to 28, 55, 25, and 50, I see this: > > > > > > > > Put in: 28 55 25 50 > > > > 011100 110111 011001 110010 > > > > > > > > Expect: 115 118 114 > > > > 01110011 01110110 01110010 > > > > > > > > Actual: 220 157 201 > > > > 11011100 10011101 11001001 > > > > > > > > I can't see where the resulting bits that actually come out are from. > > > > They don't seem to bear any relation to the bits that went in. > > > > > > > > > > > > Suggestions? (Yes, this can be done in C, but I'm trying to learn a > > > > new language, not write everything in the old one.) > > > > > > > > > > > > Darren Provine ! kilroy@elvis.rowan.edu ! http://www.rowan.edu/~kilroy > > > > "There's nothing in human experience compared to which a sendmail > config > > > > file could be considered simple." -- anonymous > > > > > > > > > _______________________________________________ > > > comp.lang.ada mailing list > > > comp.lang.ada@ada.eu.org > > > http://ada.eu.org/mailman/listinfo/comp.lang.ada > > > > > > > > > > > > > _______________________________________________ > comp.lang.ada mailing list > comp.lang.ada@ada.eu.org > http://ada.eu.org/mailman/listinfo/comp.lang.ada > >