From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.5-pre1 X-Received: by 2002:a37:5a45:: with SMTP id o66mr40670686qkb.446.1609732204190; Sun, 03 Jan 2021 19:50:04 -0800 (PST) X-Received: by 2002:a25:5c2:: with SMTP id 185mr100401592ybf.161.1609732203963; Sun, 03 Jan 2021 19:50:03 -0800 (PST) Path: eternal-september.org!reader02.eternal-september.org!news.gegeweb.eu!gegeweb.org!usenet-fr.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Sun, 3 Jan 2021 19:50:03 -0800 (PST) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: google-groups.googlegroups.com; posting-host=2601:193:4103:71a0:a9cf:2d07:fec3:bf62; posting-account=1tLBmgoAAAAfy5sC3GUezzrpVNronPA- NNTP-Posting-Host: 2601:193:4103:71a0:a9cf:2d07:fec3:bf62 References: <7fe2291a-bc12-4708-85aa-0ffbdc25b2bfn@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Re: Quick inverse square root From: Matt Borchers Injection-Date: Mon, 04 Jan 2021 03:50:04 +0000 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Xref: reader02.eternal-september.org comp.lang.ada:61022 List-Id: On Sunday, January 3, 2021 at 6:47:15 PM UTC-5, Jeffrey R. Carter wrote: > On 1/3/21 11:31 PM, Matt Borchers wrote:=20 > >=20 > > Thank you Jeff and Dmitry. I have a generic functioning now. > Glad to have been of help.=20 >=20 > Regarding the unsigned type, it seems this only works if F'Size =3D 32 or= 64, so=20 > you could write versions that use Unsigned_32 and Unsigned_64, and then m= ake=20 > your generic function do=20 >=20 > if F'Size =3D 32 then=20 > return QISR32 (A);=20 > elsif F'Size =3D 64 then=20 > return QISR64 (A);=20 > else=20 > raise Program_Error with "F'Size must be 32 or 64";=20 > end if;=20 This requires duplication of algorithm which is what the generic is suppose= d to avoid. This would be like a psuedo-generic. I did try something sim= ilar for the magic number (putting both inside the generic with an if F'Siz= e test), but the generic complained about the bit sizes being wrong in the = opposite if branch for each of the instantiations and stated that a constra= int error might be raised at run-time. Of course the constraint error neve= r occurred, but it was annoying to have the warnings and also annoying to h= ave to disable the warnings with a pragma in the code to avoid them. > But I don't understand why this exists. In what way is it better than the= =20 > (inverse) Sqrt operation of the FPU?=20 I mentioned first that this code comes from the Quake III engine. There mu= st have been a purpose for it then or maybe it was never called but left in= the source code. There are many videos about it on YouTube. I'm not real= ly a low-level graphics guy, but I think it was intended to operate on the = unit vector for intense graphics operations. I think this algorithm would work on any floating point type with a bit lay= out similar to the IEEE-754 standard regardless of how many bits were alloc= ated to the exponent and mantissa. I don't have any personal use for it. It seemed like an easy example to sho= w how Ada code can be simpler and just as powerful as C. I tried to turn i= t into a generic just as an exercise in trying to eliminate the modular typ= e from the generic interface after I realized that two types were required = that were related only in bit size. I did it with an if statement using F'= Size (similar to what you did above), but it requires duplicating a lot of = code because type declarations alone cannot be in if statements. To avoid = duplication, I think what would be necessary is a Type itself being a resul= t of an expression. Such as: i : (if F'Size =3D 32 then Unsigned_32 else Unsigned_64); =20 or a way to dynamically choose a modular type of a particular size based on= input, such as: i : Unsigned(F'Size) Wait! Can I do it like this: type Modular is mod 2**F'Size; But then, of course, the built in shift functions won't work. I need to in= vestigate this option. Another thought experiment now as I type this: I think I can eliminate the= modular type from the generic interface by declaring and overlaying a pack= ed Boolean array on the generic float type and handling the bit shift mysel= f. Of course this runs counter to the original purpose of why this routine= was created in the first place - speed of calculation. Matt