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=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,ba0524a97c5a11cf X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Path: g2news2.google.com!postnews.google.com!j35g2000prb.googlegroups.com!not-for-mail From: Syntax Issues Newsgroups: comp.lang.ada Subject: Re: Help with low level Ada Date: Thu, 17 Mar 2011 12:30:02 -0700 (PDT) Organization: http://groups.google.com Message-ID: <4506bb69-86ce-419f-af61-f573f311675a@j35g2000prb.googlegroups.com> References: <21e55933-291b-46a9-8659-3edf83d963b4@u3g2000vbe.googlegroups.com> NNTP-Posting-Host: 65.50.108.230 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1300390203 20379 127.0.0.1 (17 Mar 2011 19:30:03 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Thu, 17 Mar 2011 19:30:03 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: j35g2000prb.googlegroups.com; posting-host=65.50.108.230; posting-account=iBd8kwoAAADZsnwFNFLVlwsLLxwDLPUm User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.98 Safari/534.13,gzip(gfe) Xref: g2news2.google.com comp.lang.ada:19262 Date: 2011-03-17T12:30:02-07:00 List-Id: On Mar 17, 1:55=A0pm, Jeffrey Carter wrote: > On 03/17/2011 07:31 AM, Syntax Issues wrote: > > > > > > > > > > > unsigned ColorNormalize (vec3_t rgb){ > > =A0 =A0unsigned =A0 =A0 =A0 =A0c; > > =A0 =A0float =A0 =A0 =A0 =A0 =A0 max; > > =A0 =A0... > > =A0 =A0((byte *)&c)[0] =3D rgb[0] * max; > > =A0 =A0((byte *)&c)[1] =3D rgb[1] * max; > > =A0 =A0((byte *)&c)[2] =3D rgb[2] * max; > > =A0 =A0((byte *)&c)[3] =3D 255; > > =A0 =A0return c; > > } > > function Normalize > > =A0 =A0(Red_Green_Blue : in Vector_Color) > > =A0 =A0return Integer_Color > > =A0 =A0is > > =A0 =A0Result =A0: Integer_Color :=3D 0; > > =A0 =A0Maximum : Float_4 =A0 =A0 =A0 :=3D 0.0; > > =A0 =A0begin > > =A0 =A0 =A0 =A0 =A0 =A0... > > =A0 =A0 =A0 =A0 =A0 =A0return > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0-- ???!!??!?!? Byte(Red_Green_Bl= ue(1) * Maximum) + > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0-- ???!!??!?!? Byte(Red_Green_Bl= ue(2) * Maximum) + > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0-- ???!!??!?!? Byte(Red_Green_Bl= ue(3) * Maximum); > > =A0 =A0end Normalize; > > First, I'd probably do something like > > type Color_ID is (Red, Blue, Green); > > subtype Natural_Float_4 is Float_4 range 0.0 .. Float_4'Last; > > type Vector_Color is array (Color_ID) of Natural_Float_4; > > so I can say Red_Green_Blue (Red). (I presume that the components of > Vector_Color cannot be negative; better to make that clear in the code an= d > enforced by the language.) > > One approach to this is > > type Byte is mod 2 ** 8; > > type Color_Bytes is record > =A0 =A0 Red =A0 =A0: Byte; > =A0 =A0 Green =A0: Byte; > =A0 =A0 Blue =A0 : Byte; > =A0 =A0 Unused : Byte; > end record; > for Color_Bytes use > =A0 =A0 Red =A0 =A0at 0 range 0 .. 7; > =A0 =A0 Green =A0at 1 range 0 .. 7; > =A0 =A0 Blue =A0 at 2 range 0 .. 7; > =A0 =A0 Unused at 3 range 0 .. 7; > end record; > for Color_Bytes'Size use Integer_Color'Size; > > You may need to change the representation clause to get the components in= the > right places. > > function Convert is new Ada.Unchecked_Conversion > =A0 =A0 (Source =3D> Color_Bytes, Target =3D> Integer_Color); > > Result :=3D Color_Bytes'(Red =A0 =A0=3D> Byte (Red_Green_Blue (Red) =A0 = =A0* Maximum), > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Green =A0=3D> Byte (Red_G= reen_Blue (Green) =A0* Maximum), > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Blue =A0 =3D> Byte (Red_G= reen_Blue (Blue) =A0 * Maximum), > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Unused =3D> Byte'Last); > > return Convert (Result); > > You missed out the assignment of 255 to the 4th byte. > > Another way is to use an array of 4 Bytes that you unchecked convert to t= he > result type. > > Finally, if you use a modular type from package Interfaces you can shift = the > products into their correct positions and "or" them together. And you can= always > imitate that by multiplying by a power of 2 and adding them together: > > Result :=3D Integer_Color (Red_Green_Blue (Red) =A0 =A0* Maximum) * 2 ** = =A00 + > =A0 =A0 =A0 =A0 =A0 =A0Integer_Color (Red_Green_Blue (Green) =A0* Maximum= ) * 2 ** =A08 + > =A0 =A0 =A0 =A0 =A0 =A0Integer_Color (Red_Green_Blue (Blue) =A0 * Maximum= ) * 2 ** 16 + > =A0 =A0 =A0 =A0 =A0 =A0255 * 2 ** 24; > > The compiler will often replace these by shifts. > > > float AngleMod (float angle){ > > =A0 =A0return (360.0/65536) * ((int)(angle * (65536/360.0))& =A065535); > > } > > function Mod_Angle > > =A0 =A0(Angle : in Float_4) > > =A0 =A0return Float_4 > > =A0 =A0is > > =A0 =A0begin > > =A0 =A0 =A0 =A0 =A0 =A0return (360.0 / 65536.0) * (Integer_4_Signed(Ang= le * (65536.0 / > > 360.0)) ---???!?!?!& =A065535); > > =A0 =A0end Mod_Angle; > > Bitwise "and" is defined for all modular types. The only wrinkle is what = happens > if Angle is negative. If that's not allowed (see Natural_Float_4 above), = then > it's fairly easy: > > type Integer_4_Unsigned is mod Integer_4_Signed'Size; > > return (360.0 / 65536.0) * > =A0 =A0 =A0 =A0 Float_4 (Integer_4_Unsigned (Angle * (65536.0 / 360.0) ) = and 65535); > > Otherwise, you need to do some unchecked converting between signed and mo= dular > types of the same size: > > function Convert is new Ada.Unchecked_Conversion > =A0 =A0 (Source =3D> Integer_4_Signed, Target =3D> Integer_4_Unsigned); > > return (360.0 / 65536.0) * > =A0 =A0 =A0 =A0 Float_4 (Convert (Integer_4_Signed (Angle * (65536.0 / 36= 0.0) ) ) and > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A065535); > > (I presume that Integer_4_Signed is 4 bytes from its name, so the result = of > "and"ing that with 65535 will always be non-negative. In that case, there= 's no > need to convert back to signed before converting to Float_4.) > > > int NearestPowerOfTwo (int number, qboolean roundDown){ > > =A0 =A0int n =3D 1; > > =A0 =A0if (number<=3D 0) > > =A0 =A0 =A0 =A0 =A0 =A0return 1; > > =A0 =A0while (n< =A0number) > > =A0 =A0 =A0 =A0 =A0 =A0n<<=3D 1; > > =A0 =A0if (roundDown){ > > =A0 =A0 =A0 =A0 =A0 =A0if (n> =A0number) > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0n>>=3D 1; > > =A0 =A0} > > =A0 =A0return n; > > } > > Shift operations are defined for the modular types defined in package > Interfaces. As mentioned above, the same effect can often be obtained wit= h > multiplication and division by powers of 2, and the compiler will often r= eplace > them with shifts: > > while N < Number loop > =A0 =A0 N :=3D 2 * N; > end loop; > > if Round_Down and N > Number then > =A0 =A0 N :=3D N / 2; > end if; > > You could also use the Log function from Ada.Numerics.Generic_Elementary_= Functions: > > type Big is digits 15; > > package Math is new Ada.Numerics.Generic_Elementary_Functions > =A0 =A0 (Float_Type =3D> Big); > > N :=3D 2 ** Integer (Math.Log (Big (Number), 2.0) ); > > if N < Number then > =A0 =A0 N :=3D 2 * N; > end if; > > if Round_Down and N > Number then > =A0 =A0 N :=3D N / 2; > end if; > > -- > Jeff Carter > "We use a large, vibrating egg." > Annie Hall > 44 Excellent, I really appreciate the help.