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-Thread: a07f3367d7,6a8952cbe009f3ed X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit X-Received: by 10.66.84.38 with SMTP id v6mr1135273pay.32.1360469025923; Sat, 09 Feb 2013 20:03:45 -0800 (PST) MIME-Version: 1.0 Path: mj10ni1850pbb.1!nntp.google.com!border1.nntp.dca.giganews.com!border4.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!nrc-news.nrc.ca!goblin2!goblin.stu.neva.ru!feeder.erje.net!eu.feeder.erje.net!nuzba.szn.dk!news.jacob-sparre.dk!munin.jacob-sparre.dk!pnx.dk!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Numerical calculations: Why not use fixed point types for everything? Date: Thu, 7 Feb 2013 00:03:33 -0600 Organization: Jacob Sparre Andersen Research & Innovation Message-ID: References: <4905b963-0036-4129-8050-fb26ef0154d6@googlegroups.com> <32314026-23ae-45b8-a4c5-e589e7d79de2@googlegroups.com> <64e3c342-d042-40a2-8a16-b1f0cdff9f16@googlegroups.com> <91527f7c-0679-4c21-95c7-a07f3fff265d@googlegroups.com> <4b654b06-f2d2-4ced-8508-c10e5c84e29d@googlegroups.com> NNTP-Posting-Host: static-69-95-181-76.mad.choiceone.net X-Trace: munin.nbi.dk 1360217017 20215 69.95.181.76 (7 Feb 2013 06:03:37 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Thu, 7 Feb 2013 06:03:37 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 Date: 2013-02-07T00:03:33-06:00 List-Id: "Ada novice" wrote in message news:4b654b06-f2d2-4ced-8508-c10e5c84e29d@googlegroups.com... > On Tuesday, February 5, 2013 3:27:58 AM UTC+1, Randy Brukardt wrote: ... >> The main reason is that you almost always need to get your data from an >> array somewhere, and you use the for loop parameter ("I" in this case) to >> get the values from the array, and then use the float version of the step >> for the calculation. With the exception of benchmarks, I don't think I've >> ever written a loop that does exactly the same thing 300 times without >> changing the input data. (When such things appear to happen, usually you >> can >> refactor the expression to avoid the loop altogether, which is usually >> 300 >> times faster.) > > In this example, Frequency is changing at every index in the loop. Its > first value is -44.88 and its > final value is 67.32. This Frequency can be used further in a calculation. > > If you would have read the code well, you would have seen that the loop is > not doing 300 times > exactly the same thing. I'm not talking about doing *exactly* the same thing (that is using the same values over and over). You clearly missed my point: unless there is some varying data in the loop, you can almost always use a reorganization of the loop in order to eliminate it completely, because you are executing the same *formula* each time thru the loop. And usually, you can apply various loop-hoisting transformations to pull the useful parts of the loop out. Consider this following version of your code using the frequency in a calculation: Total := 0.0; for I in 0 .. Step-1 loop Frequency := Frequency_Start + Frequency_Step * Long_Float (I); Total := Total + Frequency*Some_Constant; end loop; Here, I've used the frequency in a calculation. "Some_Constant" is just that (or it could have been a variable not modified by the loop [a parameter, for instance], that wouldn't change anything). [Quick aside: The sorts of refactoring that I'm about to do might change the accuracy of the result -- I didn't try to figure out whether that is a danger or not.] Anyway, let's see if we can simplify this loop (this is the sort of thing a compiler would try to do, but it can't know if you can tolerate different accuracy, so it probably could not do everything you can do). First, let's get rid of the extra variable: Total := 0.0; for I in 0 .. Step-1 loop Total := Total + (Frequency_Start + Frequency_Step * Long_Float (I))*Some_Constant; end loop; Now we can distribute Some_Constant and remove a set of parens: Total := 0.0; for I in 0 .. Step-1 loop Total := Total + Frequency_Start*Some_Constant + Frequency_Step* Long_Float (I)*Some_Constant; end loop; Now, Frequency_Start*Some_Constant does not depend on the loop index, and it is going to be executed Step times. So there is no reason to execute it inside the loop. So let's pull that out of the loop: Total := Frequency_Start*Some_Constant*Long_Float(Step); for I in 0 .. Step-1 loop Total := Total + Frequency_Step* Long_Float (I)*Some_Constant; end loop; What's left here can be refactored further by noting that Frequency_Step*Some_Constant don't depend on the loop index, either. So let's pull that out of the loop, too: Total := Frequency_Start*Some_Constant*Long_Float(Step); Sum := 0; for I in 0 .. Step-1 loop Sum := Sum + I; end loop; Total := Total + Frequency_Step* Some_Constant*Long_Float(Sum); But, since Step is a constant, the value of Sum can be figured out once, declared as a constant and plugged in. (I know there is a formula for that which I forget at the moment, but that formula could be used in the constant declaration to avoid the magic number.) Total := Frequency_Start*Some_Constant*Long_Float(Step); Total := Total + Frequency_Step* Some_Constant*Long_Float(Sum_Constant); And voila! No loop! My point was that most loops can be refactored this way unless there is some varying data in them. (And the best loop execution-wise is no loop.) And indeed, most of the loops like this that I've written involve processing (summarizing, often) an array of data. In which case you need an array index; and usually you can convert that index into the factor by some technique. So iteration by fixed point values or the like makes for interesting examples, but won't happen that often in practice. Randy.