home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / csmpdigest / csmp-digest-v3-036 < prev    next >
Text File  |  2010-09-21  |  146KB  |  3,581 lines

  1. Received-Date: Thu, 16 Jun 1994 13:35:20 +0200
  2. From: pottier@clipper.ens.fr (Francois Pottier)
  3. Subject: csmp-digest-v3-036
  4. To: csmp-digest@ens.fr
  5. Date: Thu, 16 Jun 1994 13:35:08 +0200 (MET DST)
  6. X-Mailer: ELM [version 2.4 PL23]
  7. Mime-Version: 1.0
  8. Content-Type: text/plain; charset=ISO-8859-1
  9. Content-Transfer-Encoding: 8bit
  10. Errors-To: listman@ens.fr
  11. Reply-To: pottier@clipper.ens.fr
  12. X-Sequence: 39
  13.  
  14. C.S.M.P. Digest             Thu, 16 Jun 94       Volume 3 : Issue 36
  15.  
  16. Today's Topics:
  17.  
  18.         Apple Event example
  19.         Faster Square Root Algorithm
  20.         How to save alpha in PICT files?
  21.         Open Transport & ASLM
  22.         Sending the Mac Screen Image
  23.         What are Universal Headers?
  24.  
  25.  
  26.  
  27. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  28. (pottier@clipper.ens.fr).
  29.  
  30. The digest is a collection of article threads from the internet newsgroup
  31. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  32. regularly and want an archive of the discussions.  If you don't know what a
  33. newsgroup is, you probably don't have access to it.  Ask your systems
  34. administrator(s) for details.  If you don't have access to news, you may
  35. still be able to post messages to the group by using a mail server like
  36. anon.penet.fi (mail help@anon.penet.fi for more information).
  37.  
  38. Each issue of the digest contains one or more sets of articles (called
  39. threads), with each set corresponding to a 'discussion' of a particular
  40. subject.  The articles are not edited; all articles included in this digest
  41. are in their original posted form (as received by our news server at
  42. nef.ens.fr).  Article threads are not added to the digest until the last
  43. article added to the thread is at least two weeks old (this is to ensure that
  44. the thread is dead before adding it to the digest).  Article threads that
  45. consist of only one message are generally not included in the digest.
  46.  
  47. The digest is officially distributed by two means, by email and ftp.
  48.  
  49. If you want to receive the digest by mail, send email to listserv@ens.fr
  50. with no subject and one of the following commands as body:
  51.     help                        Sends you a summary of commands
  52.     subscribe csmp-digest Your Name    Adds you to the mailing list
  53.     signoff csmp-digest            Removes you from the list
  54. Once you have subscribed, you will automatically receive each new
  55. issue as it is created.
  56.  
  57. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  58. Questions related to the ftp site should be directed to
  59. scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
  60. digest are available there.
  61.  
  62. Also, the digests are available to WAIS users.  To search back issues
  63. with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
  64. http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
  65.  
  66.  
  67. -------------------------------------------------------
  68.  
  69. >From farago@onyx.ill.fr (Bela Farago)
  70. Subject: Apple Event example
  71. Date: Thu, 2 Jun 94 13:06:18 GMT
  72. Organization: ILL - Grenoble FRANCE
  73.  
  74. Hi,
  75.  
  76. please forgive me if it is trivial but I am programming just by hobby (well
  77. not really but this is not my main job)
  78. I need to write a rather trivial code resource which sends the equivalent of
  79. the following AppleScript
  80.  
  81. tell application anApplication
  82.     save document 1
  83. end tell
  84.  
  85. An Application is an application :)
  86.  
  87. It is hard to digest the volume VI of IM. and I could not find simple
  88. example on ftp.apple.com. (I did find some but were not very clear to me) I
  89. am bit lost in descriptors and direct objects etc. Could anybody give me
  90. pointers to simple examples?
  91.                                     Bela Farago (farago@ill.fr)
  92.  
  93. ps: No flames please, you can always just ignore this message.
  94.  
  95. +++++++++++++++++++++++++++
  96.  
  97. >From greer@utdallas.edu (Dale M. Greer)
  98. Date: 2 Jun 1994 16:54:39 GMT
  99. Organization: The University of Texas at Dallas
  100.  
  101. Bela Farago (farago@onyx.ill.fr) wrote:
  102. > Hi,
  103.  
  104. > please forgive me if it is trivial but I am programming just by hobby (well
  105. > not really but this is not my main job)
  106. > I need to write a rather trivial code resource which sends the equivalent of
  107. > the following AppleScript
  108.  
  109. > tell application anApplication
  110. >     save document 1
  111. > end tell
  112.  
  113. > An Application is an application :)
  114.  
  115. > It is hard to digest the volume VI of IM. and I could not find simple
  116. > example on ftp.apple.com. (I did find some but were not very clear to me) I
  117. > am bit lost in descriptors and direct objects etc. Could anybody give me
  118. > pointers to simple examples?
  119. >                                     Bela Farago (farago@ill.fr)
  120.  
  121. > ps: No flames please, you can always just ignore this message.
  122.  
  123.  
  124. Here's how I did it.
  125.  
  126. /**************************************************** MyCreateDocContainer */
  127. // 07-APR-94 : Dale M. Greer
  128.  
  129. #pragma segment AEvents
  130. void MyCreateDocContainer(AEDesc *myDocContainer, char *docName)
  131. {
  132.     AEDesc myDocDescRec, nullDescRec;
  133.     OSErr err;
  134.  
  135.     // Prepare to make something from nothing
  136.     err = AECreateDesc(typeNull, nil, 0, &nullDescRec);
  137.  
  138.     // This document container just contains the document name
  139.     err = AECreateDesc(typeChar, docName, strlen(docName), &myDocDescRec);
  140.  
  141.     // Encapsulate the object
  142.     err = CreateObjSpecifier((DescType)cDocument, &nullDescRec, 
  143.         (DescType)formName, &myDocDescRec, true, myDocContainer);
  144.  
  145.     AEDisposeDesc(&nullDescRec);
  146. }
  147.  
  148. /********************************************************** SaveDocumentAs */
  149. // 07-APR-94 : Dale M. Greer
  150.  
  151. #pragma segment AEvents
  152. void SaveDocumentAs(AEAddressDesc *theAddress, char *docName, char *saveName)
  153. {
  154.     OSErr err;
  155.     AppleEvent appleEvent, reply;
  156.     AEDesc myDocDescRec, theName;
  157.  
  158.     err = AECreateAppleEvent(kAECoreSuite, kAESave, theAddress,
  159.             kAutoGenerateReturnID, 1L, &appleEvent);
  160.  
  161.     // Make the doc container
  162.     MyCreateDocContainer(&myDocDescRec, docName);
  163.  
  164.     // Append it to the appleEvent
  165.     AEPutParamDesc(&appleEvent, keyDirectObject, &myDocDescRec);
  166.  
  167.     // Append the new filename descriptor to the appleEvent
  168.     AECreateDesc(typeChar, saveName, strlen(saveName), &theName);
  169.     AEPutParamDesc(&appleEvent, keyAEFile, &theName);
  170.  
  171.     // Send it to the Application
  172.     err = AESend(&appleEvent, &reply, kAEWaitReply + kAENeverInteract,
  173.             kAENormalPriority, kAEDefaultTimeout,
  174.             (IdleProcPtr) MyIdleFunction, nil);
  175.  
  176.     AEDisposeDesc(&myDocDescRec);
  177.     AEDisposeDesc(&appleEvent);
  178.     AEDisposeDesc(&reply);
  179. }
  180.  
  181.  
  182. You get the address of the target application when you launch it, or if it
  183. is already launched, use the following routine, where "creator" is the
  184. creator type of your application.  For example, this creator type is
  185. 'XCEL' for Excel, 'ttxt' for TeachText, etc.
  186.  
  187. // This function originated from James "im" Beninghaus of Apple DTS
  188. /*********************************************************** AppLaunched */
  189. // Find the process serial number of your application
  190.  
  191. #pragma segment Launch
  192. Boolean AppLaunched(AEAddressDesc *theAddress, OSType creator,
  193.                     ProcessSerialNumber *PSN)
  194. {
  195.     OSErr                osErr;
  196.     ProcessSerialNumber process;
  197.     ProcessInfoRec        procInfo;
  198.     Str255                procName;
  199.     FSSpec procSpec;
  200.     
  201.     osErr = noErr;
  202.     process.highLongOfPSN = 0;
  203.     process.lowLongOfPSN  = 0;
  204.     
  205.     procInfo.processInfoLength    = sizeof(procInfo);
  206.     procInfo.processName        = procName;
  207.     procInfo.processAppSpec        = &procSpec;
  208.  
  209.     while (procNotFound != (osErr = GetNextProcess(&process))) {
  210.         if (noErr == (osErr = GetProcessInformation(&process, &procInfo))) {
  211.             if (procInfo.processSignature == creator) {
  212.                 AECreateDesc(typeProcessSerialNumber, (Ptr)&process, 
  213.                     sizeof(ProcessSerialNumber), theAddress);
  214.                     *PSN = process;
  215.                 return(true);
  216.             }
  217.         }
  218.     }
  219.     return(false);
  220. }
  221.  
  222. In summary, the program snippet accomplishing what you desire would
  223. look like this.
  224.  
  225. if (AppLaunched(&theAddress, theCreator, &PSN) {
  226.     SaveDocumentAs(&theAddress, &docName, &saveName);
  227. }
  228.  
  229. If the application is not already launched, there are a number of ways
  230. to launch it, but I will leave that as an exercise for the reader, or
  231. for a later tutorial if you're still having problems.
  232.  
  233. --
  234.  
  235. Dale Greer, greer@utdallas.edu
  236. "They know that it is human nature to take up causes whereby a man may
  237.  oppress his neighbor, no matter how unjustly. ... Hence they have had
  238.  no trouble in finding men who would preach the damnability and heresy
  239.  of the new doctrine from the very pulpit..." - Galileo Galilei, 1615
  240.  
  241.  
  242. ---------------------------
  243.  
  244. >From busfield@hurricane.seas.ucla.edu (John D. Busfield)
  245. Subject: Faster Square Root Algorithm
  246. Date: Tue, 3 May 1994 17:23:52 GMT
  247. Organization: School of Engineering & Applied Science, UCLA.
  248.  
  249.     Does anyone have an algorithm or code for computing square roots.
  250. The emphasis is on speed rather than accuracy in that I only need the
  251. result rounded to the nearest integer (ie sqrt(1000) = 31 or 32).
  252. Thanks in advance.
  253.  
  254. John Busfield
  255. busfield@hurricane.seas.ucla.edu
  256.  
  257.  
  258. +++++++++++++++++++++++++++
  259.  
  260. >From rmah@panix.com (Robert S. Mah)
  261. Date: Tue, 03 May 1994 17:41:55 -0500
  262. Organization: One Step Beyond
  263.  
  264. busfield@hurricane.seas.ucla.edu (John D. Busfield) wrote:
  265.  
  266. >     Does anyone have an algorithm or code for computing square roots.
  267. > The emphasis is on speed rather than accuracy in that I only need the
  268. > result rounded to the nearest integer (ie sqrt(1000) = 31 or 32).
  269.  
  270. There is an article on generating very fast square root aproximations
  271. in the book "Graphics Gems", Ed. Glassner. 
  272.  
  273. It generates a lookup table which is indexed by munging the exponent
  274. of the argument and then uses the mantissa to do an (linear?) 
  275. aproximation to the final result.  It's fairly accurate to within a few
  276. decimal points.  I think the source code is also available somewhere 
  277. on the net, but I'm afraid I don't know where.
  278.  
  279. Another option, since you only want integer aproximations, is to create a 
  280. table of squares and do a binary search over it.  A 1000 element table 
  281. will give you a range of 1->1,000,000 with an average of log2(1000) = 10 
  282. lookups using a simple binary search.  A table with 32K or so elements will
  283.  
  284. have a range of 1->1,000,000,000 and will be searchable in log2(32K) = 30 
  285. lookups.  If you can spare a few dozen K, then this may be fast enough.
  286.  
  287. Cheers,
  288. Rob
  289. ___________________________________________________________________________
  290. Robert S. Mah  -=-  One Step Beyond  -=-  212-947-6507  -=-  rmah@panix.com
  291.  
  292. +++++++++++++++++++++++++++
  293.  
  294. >From gewekean@studentg.msu.edu (Andrew Geweke)
  295. Date: Tue,  3 May 1994 20:56:35 -0400
  296. Organization: Michigan State University
  297.  
  298. In article <rmah-030594174155@rmah.dialup.access.net>, rmah@panix.com (Robert 
  299. S. Mah) writes:
  300. > Another option, since you only want integer aproximations, is to create 
  301. > a table of squares and do a binary search over it.  A 1000 element 
  302. > table will give you a range of 1->1,000,000 with an average of log2
  303. > (1000) = 10 lookups using a simple binary search.  A table with 32K or 
  304. > so elements will 
  305. >  
  306. > have a range of 1->1,000,000,000 and will be searchable in log2(32K) = 30 
  307. > lookups.  If you can spare a few dozen K, then this may be fast enough. 
  308.  
  309. Actually, I once found this algorithm:
  310.  
  311. int intSqrt (int num) {
  312.    for (i = j = 1, k = 3; num > j; j += (k+=2), ++i)
  313.           ;
  314.  
  315.    return i;
  316. }
  317.  
  318. Note that this algorithm rounds up, not down. I'm not sure exactly how 
  319. correct this is (I just coded it off the top of my head) but you get the 
  320. basic idea in any case. Adding the odd integers gives you the squares; i.e. 1 
  321. = 1; 1 + 3 = 4; 1 + 3 + 5 = 9; 1 + 3 + 5 + 7 = 16; 1 + 3 + 5 + 7 + 9 = 25; 
  322. and so on.
  323.  
  324. I don't know how fast this is in your specific instance, but it should be 
  325. quite fast.
  326.  
  327.  
  328.  
  329.  
  330.  
  331. +++++++++++++++++++++++++++
  332.  
  333. >From rmah@panix.com (Robert S. Mah)
  334. Date: Tue, 03 May 1994 22:04:22 -0500
  335. Organization: One Step Beyond
  336.  
  337. gewekean@studentg.msu.edu (Andrew Geweke) wrote:
  338.  
  339. > rmah@panix.com (Robert  S. Mah) writes:
  340. > > Another option, since you only want integer aproximations, is to create 
  341. > > a table of squares and do a binary search over it.  A 1000 element 
  342. > > [...]
  343. > > have a range of 1->1,000,000,000 and will be searchable in log2(32K) = 30 
  344. > > lookups.  If you can spare a few dozen K, then this may be fast enough. 
  345. > Actually, I once found this algorithm:
  346. > int intSqrt (int num) {
  347. >    for (i = j = 1, k = 3; num > j; j += (k+=2), ++i)
  348. >           ;
  349. >    return i;
  350. > }
  351. > Note that this algorithm rounds up, not down. I'm not sure exactly how 
  352. > correct this is (I just coded it off the top of my head) but you get the 
  353. > basic idea in any case. Adding the odd integers gives you the squares; 
  354. > i.e. 1  = 1; 1 + 3 = 4; 1 + 3 + 5 = 9; 1 + 3 + 5 + 7 = 16; 1 + 3 + 5 + 
  355. > 7 + 9 = 25;  and so on.
  356. > I don't know how fast this is in your specific instance, but it should  
  357. > be quite fast.
  358.  
  359. That's a great little algorithm!  That sequence looks _so_ familiar, but
  360. for the life of me, I can't recall the name...
  361.  
  362. Anyway, it looks like it would be order O(sqrt(n)) where n is the argument 
  363. to the function.  Only a problem if the domain range for the application 
  364. is large, that is Sqrt(10000) would take 10 times as long as Sqrt(100).  
  365. However, unlike the table method, the upper bounds isn't fixed at compile
  366. time.
  367.  
  368. Cheers,
  369. Rob
  370. ___________________________________________________________________________
  371. Robert S. Mah  -=-  One Step Beyond  -=-  212-947-6507  -=-  rmah@panix.com
  372.  
  373. +++++++++++++++++++++++++++
  374.  
  375. >From pottier@corvette.ens.fr (Francois Pottier)
  376. Date: 4 May 1994 09:42:29 GMT
  377. Organization: Ecole Normale Superieure, PARIS, France
  378.  
  379. In article <busfield.767985832@hurricane>,
  380. John D. Busfield <busfield@hurricane.seas.ucla.edu> wrote:
  381.  
  382. >    Does anyone have an algorithm or code for computing square roots.
  383.  
  384.  
  385. There was a thread on this subject about a year ago. Here's what
  386. I kept:
  387.  
  388. - -----------------------------------------------------------------------
  389.  
  390.  
  391. >Does somebody have code or an algorithm for extracting a long integer
  392. >square root and returning an integer?
  393.  
  394. There was a long series of letters in Dr.  Dobbs' Journal a few years
  395. back that I was a part of.  Here are two 'competing' subroutines for the
  396. 68000 that I wrote.  One is a Newton-Raphson iterator, the other a
  397. hybrid of three different subroutines using two different methods,
  398. heavily optimized for speed.  The non-Newton one is faster in some cases
  399. and slower in others.  Choosing one as 'best' depends on what kind of
  400. input ranges you expect to see most often.  Newton's time doesn't vary
  401. much on the average based on the input argument.  The non-Newton one
  402. ranges from a lot better (small arguments) to a little worse (large
  403. arguments), but is always better than Newton's worst case.  Don't
  404. neglect the fact that on a FPU-equipped machine it may be faster to use
  405. floating point.  I've done no research into this possibility, nor have I
  406. timed this stuff on any 68020+ system.  The speed balance is no doubt
  407. different then.  (For that matter, the 68000 testbed had no wait states
  408. nor interrupt system overhead, which doesn't necessarily apply to a
  409. 68000 PowerBook, and certainly doesn't apply to a Mac+ or earlier.)
  410.  
  411. I'm personally fond of the non-Newton version, because the algorithm
  412. only uses shifts and adds, so it could be implemented in microcode with
  413. about same speed as a divide.
  414.  
  415. *************************************************************************
  416. *                                                                       *
  417. *       Integer Square Root (32 to 16 bit).                             *
  418. *                                                                       *
  419. *       (Newton-Raphson method).                                        *
  420. *                                                                       *
  421. *       Call with:                                                      *
  422. *               D0.L = Unsigned number.                                 *
  423. *                                                                       *
  424. *       Returns:                                                        *
  425. *               D0.L = SQRT(D0.L)                                       *
  426. *                                                                       *
  427. *       Notes:  Result fits in D0.W, but is valid in longword.          *
  428. *               Takes from 338 cycles (1 shift, 1 division) to          *
  429. *               1580 cycles (16 shifts, 4 divisions)  (including rts).  *
  430. *               Averages 854 cycles measured over first 65535 roots.    *
  431. *               Averages 992 cycles measured over first 500000 roots.   *
  432. *                                                                       *
  433. *************************************************************************
  434.  
  435.         .globl lsqrt
  436. *                       Cycles
  437. lsqrt   movem.l d1-d2,-(sp) (24)
  438.         move.l d0,d1    (4)     ; Set up for guessing algorithm.
  439.         beq.s return    (10/8)  ; Don't process zero.
  440.         moveq #1,d2     (4)
  441.  
  442. guess   cmp.l d2,d1     (6)     ; Get a guess that is guaranteed to be
  443.         bls.s newton    (10/8)  ; too high, but not by much, by dividing the
  444.         add.l d2,d2     (8)     ; argument by two and multiplying a 1 by 2
  445.         lsr.l #1,d1     (10)    ; until the power of two passes the modified
  446.         bra.s guess     (10)    ; argument, then average these two numbers.
  447.  
  448. newton  add.l d1,d2     (8)     ; Average the two guesses.
  449.         lsr.l #1,d2     (10)
  450.         move.l d0,d1    (4)     ; Generate the next approximation(s)
  451.         divu d2,d1      (140)   ; via the Newton-Raphson method.
  452.         bvs.s done      (10/8)  ; Handle out-of-range input (cheats!)
  453.         cmp.w d1,d2     (4)     ; Have we converged?
  454.         bls.s done      (10/8)
  455.         swap d1         (4)     ; No, kill the remainder so the
  456.         clr.w d1        (4)     ; next average comes out right.
  457.         swap d1         (4)
  458.         bra.s newton    (10)
  459.  
  460. done    clr.w d0        (4)     ; Return a word answer in a longword.
  461.         swap d0         (4)
  462.         move.w d2,d0    (4)
  463. return  movem.l (sp)+,d1-d2  (28)
  464.         rts             (16)
  465.  
  466.         end
  467. *************************************************************************
  468. *                                                                       *
  469. *       Integer Square Root (32 to 16 bit).                             *
  470. *                                                                       *
  471. *       (Exact method, not approximate).                                *
  472. *                                                                       *
  473. *       Call with:                                                      *
  474. *               D0.L = Unsigned number.                                 *
  475. *                                                                       *
  476. *       Returns:                                                        *
  477. *               D0.L = SQRT(D0.L)                                       *
  478. *                                                                       *
  479. *       Notes:  Result fits in D0.W, but is valid in longword.          *
  480. *               Takes from 122 to 1272 cycles (including rts).          *
  481. *               Averages 610 cycles measured over first 65535 roots.    *
  482. *               Averages 1104 cycles measured over first 500000 roots.  *
  483. *                                                                       *
  484. *************************************************************************
  485.  
  486.         .globl lsqrt
  487. *                       Cycles
  488. lsqrt   tst.l d0        (4)     ; Skip doing zero.
  489.         beq.s done      (10/8)
  490.         cmp.l #$10000,d0 (14)   ; If is a longword, use the long routine.
  491.         bhs.s glsqrt    (10/8)
  492.         cmp.w #625,d0   (8)     ; Would the short word routine be quicker?
  493.         bhi.s gsqrt     (10/8)  ; No, use general purpose word routine.
  494. *                               ; Otherwise fall into special routine.
  495. *
  496. *  For speed, we use three exit points.
  497. *  This is cheesy, but this is a speed-optimized subroutine!
  498.  
  499.         page
  500. *************************************************************************
  501. *                                                                       *
  502. *       Faster Integer Square Root (16 to 8 bit).  For small arguments. *
  503. *                                                                       *
  504. *       (Exact method, not approximate).                                *
  505. *                                                                       *
  506. *       Call with:                                                      *
  507. *               D0.W = Unsigned number.                                 *
  508. *                                                                       *
  509. *       Returns:                                                        *
  510. *               D0.W = SQRT(D0.W)                                       *
  511. *                                                                       *
  512. *       Notes:  Result fits in D0.B, but is valid in word.              *
  513. *               Takes from 72 (d0=1) to 504 (d0=625) cycles             *
  514. *               (including rts).                                        *
  515. *                                                                       *
  516. *       Algorithm supplied by Motorola.                                 *
  517. *                                                                       *
  518. *************************************************************************
  519.  
  520. * Use the theorem that a perfect square is the sum of the first
  521. * sqrt(arg) number of odd integers.
  522.  
  523. *                       Cycles
  524.         move.w d1,-(sp) (8)
  525.         move.w #-1,d1   (8)
  526. qsqrt1  addq.w #2,d1    (4)
  527.         sub.w d1,d0     (4)
  528.         bpl qsqrt1      (10/8)
  529.         asr.w #1,d1     (8)
  530.         move.w d1,d0    (4)
  531.         move.w (sp)+,d1 (12)
  532. done    rts             (16)
  533.  
  534.         page
  535. *************************************************************************
  536. *                                                                       *
  537. *       Integer Square Root (16 to 8 bit).                              *
  538. *                                                                       *
  539. *       (Exact method, not approximate).                                *
  540. *                                                                       *
  541. *       Call with:                                                      *
  542. *               D0.W = Unsigned number.                                 *
  543. *                                                                       *
  544. *       Returns:                                                        *
  545. *               D0.L = SQRT(D0.W)                                       *
  546. *                                                                       *
  547. *       Uses:   D1-D4 as temporaries --                                 *
  548. *               D1 = Error term;                                        *
  549. *               D2 = Running estimate;                                  *
  550. *               D3 = High bracket;                                      *
  551. *               D4 = Loop counter.                                      *
  552. *                                                                       *
  553. *       Notes:  Result fits in D0.B, but is valid in word.              *
  554. *                                                                       *
  555. *               Takes from 544 to 624 cycles (including rts).           *
  556. *                                                                       *
  557. *               Instruction times for branch-type instructions          *
  558. *               listed as (X/Y) are for (taken/not taken).              *
  559. *                                                                       *
  560. *************************************************************************
  561.  
  562. *                       Cycles
  563. gsqrt   movem.l d1-d4,-(sp) (40)
  564.         move.w #7,d4    (8)     ; Loop count (bits-1 of result).
  565.         clr.w d1        (4)     ; Error term in D1.
  566.         clr.w d2        (4)
  567. sqrt1   add.w d0,d0     (4)     ; Get 2 leading bits a time and add
  568.         addx.w d1,d1    (4)     ; into Error term for interpolation.
  569.         add.w d0,d0     (4)     ; (Classical method, easy in binary).
  570.         addx.w d1,d1    (4)
  571.         add.w d2,d2     (4)     ; Running estimate * 2.
  572.         move.w d2,d3    (4)
  573.         add.w d3,d3     (4)
  574.         cmp.w d3,d1     (4)
  575.         bls.s sqrt2     (10/8)  ; New Error term > 2* Running estimate?
  576.         addq.w #1,d2    (4)     ; Yes, we want a '1' bit then.
  577.         addq.w #1,d3    (4)     ; Fix up new Error term.
  578.         sub.w d3,d1     (4)
  579. sqrt2   dbra d4,sqrt1   (10/14) ; Do all 8 bit-pairs.
  580.         move.w d2,d0    (4)
  581.         movem.l (sp)+,d1-d4 (44)
  582.         rts             (16)
  583.  
  584.         page
  585. *************************************************************************
  586. *                                                                       *
  587. *       Integer Square Root (32 to 16 bit).                             *
  588. *                                                                       *
  589. *       (Exact method, not approximate).                                *
  590. *                                                                       *
  591. *       Call with:                                                      *
  592. *               D0.L = Unsigned number.                                 *
  593. *                                                                       *
  594. *       Returns:                                                        *
  595. *               D0.L = SQRT(D0.L)                                       *
  596. *                                                                       *
  597. *       Uses:   D1-D4 as temporaries --                                 *
  598. *               D1 = Error term;                                        *
  599. *               D2 = Running estimate;                                  *
  600. *               D3 = High bracket;                                      *
  601. *               D4 = Loop counter.                                      *
  602. *                                                                       *
  603. *       Notes:  Result fits in D0.W, but is valid in longword.          *
  604. *                                                                       *
  605. *               Takes from 1080 to 1236 cycles (including rts.)         *
  606. *                                                                       *
  607. *               Two of the 16 passes are unrolled from the loop so that *
  608. *               quicker instructions may be used where there is no      *
  609. *               danger of overflow (in the early passes).               *
  610. *                                                                       *
  611. *               Instruction times for branch-type instructions          *
  612. *               listed as (X/Y) are for (taken/not taken).              *
  613. *                                                                       *
  614. *************************************************************************
  615.  
  616. *                       Cycles
  617. glsqrt  movem.l d1-d4,-(sp) (40)
  618.         moveq #13,d4    (4)     ; Loop count (bits-1 of result).
  619.         moveq #0,d1     (4)     ; Error term in D1.
  620.         moveq #0,d2     (4)
  621. lsqrt1  add.l d0,d0     (8)     ; Get 2 leading bits a time and add
  622.         addx.w d1,d1    (4)     ; into Error term for interpolation.
  623.         add.l d0,d0     (8)     ; (Classical method, easy in binary).
  624.         addx.w d1,d1    (4)
  625.         add.w d2,d2     (4)     ; Running estimate * 2.
  626.         move.w d2,d3    (4)
  627.         add.w d3,d3     (4)
  628.         cmp.w d3,d1     (4)
  629.         bls.s lsqrt2    (10/8)  ; New Error term > 2* Running estimate?
  630.         addq.w #1,d2    (4)     ; Yes, we want a '1' bit then.
  631.         addq.w #1,d3    (4)     ; Fix up new Error term.
  632.         sub.w d3,d1     (4)
  633. lsqrt2  dbra d4,lsqrt1  (10/14) ; Do first 14 bit-pairs.
  634.  
  635.         add.l d0,d0     (8)     ; Do 15-th bit-pair.
  636.         addx.w d1,d1    (4)
  637.         add.l d0,d0     (8)
  638.         addx.l d1,d1    (8)
  639.         add.w d2,d2     (4)
  640.         move.l d2,d3    (4)
  641.         add.w d3,d3     (4)
  642.         cmp.l d3,d1     (6)
  643.         bls.s lsqrt3    (10/8)
  644.         addq.w #1,d2    (4)
  645.         addq.w #1,d3    (4)
  646.         sub.l d3,d1     (8)
  647.  
  648. lsqrt3  add.l d0,d0     (8)     ; Do 16-th bit-pair.
  649.         addx.l d1,d1    (8)
  650.         add.l d0,d0     (8)
  651.         addx.l d1,d1    (8)
  652.         add.w d2,d2     (4)
  653.         move.l d2,d3    (4)
  654.         add.l d3,d3     (8)
  655.         cmp.l d3,d1     (6)
  656.         bls.s lsqrt4    (10/8)
  657.         addq.w #1,d2    (4)
  658. lsqrt4  move.w d2,d0    (4)
  659.         movem.l (sp)+,d1-d4 (44)
  660.         rts             (16)
  661.  
  662.         end
  663. -- 
  664. +----------------+
  665. ! II      CCCCCC !  Jim Cathey
  666. ! II  SSSSCC     !  ISC-Bunker Ramo
  667. ! II      CC     !  TAF-C8;  Spokane, WA  99220
  668. ! IISSSS  CC     !  UUCP: uunet!isc-br!jimc (jimc@isc-br.isc-br.com)
  669. ! II      CCCCCC !  (509) 927-5757
  670. +----------------+
  671.  
  672. - -----------------------------------------------------------------------------
  673.  
  674. /*
  675.  * ISqrt--
  676.  *     Find square root of n.  This is a Newton's method approximation,
  677.  * converging in 1 iteration per digit or so.  Finds floor(sqrt(n) + 0.5).
  678.  */
  679. int ISqrt(register int n)
  680. {
  681.     register int i;
  682.     register long k0, k1, nn;
  683.  
  684.     for (nn = i = n, k0 = 2; i > 0; i >>= 2, k0 <<= 1)
  685.         ;
  686.     nn <<= 2;
  687.     for (;;) {
  688.         k1 = (nn / k0 + k0) >> 1;
  689.         if (((k0 ^ k1) & ~1) == 0)
  690.             break;
  691.         k0 = k1;
  692.     }
  693.     return (int) ((k1 + 1) >> 1);    
  694. }
  695.  
  696. -- 
  697. Joseph Nathan Hall  |  Joseph's Rule of Thumb: Most folks aren't interested
  698. Software Architect  |                          in your rules of thumb.
  699. Gorca Systems Inc.  |  ----- joseph@joebloe.maple-shade.nj.us (home) -----
  700. (on assignment)     |        (602) 732-2549 jnhall@sat.mot.com (work)
  701.  
  702. - -----------------------------------------------------------------------------
  703.  
  704. Here's an article I saved from c.s.m.p four months ago.  Strangely, it
  705. was only distributed in North America.  I don't know how fast it works
  706. in practice, but there are no multiplications or divisions in its inner
  707. loop, which is promising.
  708.  
  709.  
  710. #include <math.h>
  711.  
  712. /*
  713.  * It requires more space to describe this implementation of the manual
  714.  * square root algorithm than it did to code it.  The basic idea is that
  715.  * the square root is computed one bit at a time from the high end.  Because
  716.  * the original number is 32 bits (unsigned), the root cannot exceed 16 bits
  717.  * in length, so we start with the 0x8000 bit.
  718.  *
  719.  * Let "x" be the value whose root we desire, "t" be the square root
  720.  * that we desire, and "s" be a bitmask.  A simple way to compute
  721.  * the root is to set "s" to 0x8000, and loop doing the following:
  722.  *
  723.  *    t = 0;
  724.  *    s = 0x8000;
  725.  *    do {
  726.  *        if ((t + s) * (t + s) <= x)
  727.  *            t += s;
  728.  *        s >>= 1;
  729.  *    while (s != 0);
  730.  *
  731.  * The primary disadvantage to this approach is the multiplication.  To
  732.  * eliminate this, we begin simplying.  First, we observe that
  733.  *
  734.  *    (t + s) * (t + s) == (t * t) + (2 * t * s) + (s * s)
  735.  *
  736.  * Therefore, if we redefine "x" to be the original argument minus the
  737.  * current value of (t * t), we can determine if we should add "s" to
  738.  * the root if
  739.  *
  740.  *    (2 * t * s) + (s * s) <= x
  741.  *
  742.  * If we define a new temporary "nr", we can express this as
  743.  *
  744.  *    t = 0;
  745.  *    s = 0x8000;
  746.  *    do {
  747.  *        nr = (2 * t * s) + (s * s);
  748.  *        if (nr <= x) {
  749.  *            x -= nr;
  750.  *            t += s;
  751.  *        }
  752.  *        s >>= 1;
  753.  *    while (s != 0);
  754.  *
  755.  * We can improve the performance of this by noting that "s" is always a
  756.  * power of two, so multiplication by "s" is just a shift.  Also, because
  757.  * "s" changes in a predictable manner (shifted right after each iteration)
  758.  * we can precompute (0x8000 * t) and (0x8000 * 0x8000) and then adjust
  759.  * them by shifting after each step.  First, we let "m" hold the value
  760.  * (s * s) and adjust it after each step by shifting right twice.  We
  761.  * also introduce "r" to hold (2 * t * s) and adjust it after each step
  762.  * by shifting right once.  When we update "t" we must also update "r",
  763.  * and we do so by noting that (2 * (old_t + s) * s) is the same as
  764.  * (2 * old_t * s) + (2 * s * s).  Noting that (s * s) is "m" and that
  765.  * (r + 2 * m) == ((r + m) + m) == (nr + m):
  766.  *
  767.  *    t = 0;
  768.  *    s = 0x8000;
  769.  *    m = 0x40000000;
  770.  *    r = 0;
  771.  *    do {
  772.  *        nr = r + m;
  773.  *        if (nr <= x) {
  774.  *            x -= nr;
  775.  *            t += s;
  776.  *            r = nr + m;
  777.  *        }
  778.  *        s >>= 1;
  779.  *        r >>= 1;        
  780.  *        m >>= 2;
  781.  *    } while (s != 0);
  782.  *
  783.  * Finally, we note that, if we were using fractional arithmetic, after
  784.  * 16 iterations "s" would be a binary 0.5, so the value of "r" when
  785.  * the loop terminates is (2 * t * 0.5) or "t".  Because the values in
  786.  * "t" and "r" are identical after the loop terminates, and because we
  787.  * do not otherwise use "t"  explicitly within the loop, we can omit it.
  788.  * When we do so, there is no need for "s" except to terminate the loop,
  789.  * but we observe that "m" will become zero at the same time as "s",
  790.  * so we can use it instead.
  791.  *
  792.  * The result we have at this point is the floor of the square root.  If
  793.  * we want to round to the nearest integer, we need to consider whether
  794.  * the remainder in "x" is greater than or equal to the difference
  795.  * between ((r + 0.5) * (r + 0.5)) and (r * r).  Noting that the former
  796.  * quantity is (r * r + r + 0.25), we want to check if the remainder is
  797.  * greater than or equal to (r + 0.25).  Because we are dealing with
  798.  * integers, we can't have equality, so we round up if "x" is strictly
  799.  * greater than "r":
  800.  *
  801.  *    if (x > r)
  802.  *        r++;
  803.  */
  804.  
  805. unsigned int isqrt(unsigned long x)
  806. {
  807.     unsigned long r, nr, m;
  808.  
  809.     r = 0;
  810.     m = 0x40000000;
  811.     do {
  812.         nr = r + m;
  813.         if (nr <= x) {
  814.             x -= nr;
  815.             r = nr + m;
  816.         }
  817.         r >>= 1;
  818.         m >>= 2;
  819.     } while (m != 0);
  820.  
  821.     if (x > r)
  822.         r++;
  823.     return(r);
  824. }
  825. --
  826. (Dr.) John Bruner, Deputy Director            bruner@csrd.uiuc.edu
  827. Center for Supercomputing Research & Development    (217) 244-4476 (voice)
  828. University of Illinois at Urbana-Champaign        (217) 244-1351 (FAX)
  829. 465 CSRL, MC-264; 1308 West Main St.; Urbana, IL  61801-2307
  830.  
  831.  
  832. -- 
  833.  Jamie McCarthy        Internet: k044477@kzoo.edu    AppleLink: j.mccarthy
  834.  
  835. - -----------------------------------------------------------------------------
  836.  
  837. Then there is the easy way - use the toolbox:
  838.  
  839. #define LongSqrt(x) ((short)(FracSqrt((Fract)(x)) >> 15))
  840.  
  841. FractSqrt is in FixMath.h. This works because given two fixed point number 
  842. of the form x.y, where x is the number of bits before the decimal point 
  843. and y is the number of bits after the decimal point, twos complement 
  844. multiplication will yield a result of: x1.y1 * x2.y2 = x1+x2.y1+y2. If the 
  845. numbers are the same format, this becomes x.y * x.y = 2x.2y. This holds 
  846. for squaring a number also: x.y^2 = 2x.2y. The sqrt is then sqrt(x.y) = 
  847. x/2.y/2. FracSqrt is of the form FracSqrt(2.30) = 2.30. Since we know how 
  848. sqrt works this can also be expressed as FracSqrt(x.y) = x/2.y/2 << 15 
  849. (This is a "virtual" shift since the calculation is compleated with more 
  850. precision the 15 bits shifted in are "real" and not 0). So if you want to 
  851. use FracSqrt for a long you get FracSqrt(32.0) = 16.0 << 15. So you shift 
  852. the result down be 15 to get a short (you can add 1 << 14 prior to 
  853. shifting down by 15 to round instead of truncing your result). If you 
  854. wanted a long sqrt with a 16.16 (Fixed) result you would use:
  855.  
  856. #define LongFixedSqrt(x) ((Fixed)(FracSqrt((Fract)(x)) << 1))
  857.  
  858. If you want a Fixed (16.16) sqrt with a Fixed result (16.16) you would use:
  859.  
  860. #define FixedSqrt(x) ((Fixed)FracSqrt((Fract)(x)) >> 7))
  861.  
  862. You can do this kind of work with all of the fixed point routines and 
  863. standard operators.
  864.  
  865. Sean Parent
  866.  
  867.  
  868.  
  869. -- 
  870. Francois Pottier                                            pottier@dmi.ens.fr
  871. - ----------------------------------------------------------------------------
  872. This area dedicated to the preservation of endangered species.         "Moof!"
  873.  
  874. +++++++++++++++++++++++++++
  875.  
  876. >From christer@cs.umu.se (Christer Ericson)
  877. Date: Wed, 4 May 1994 12:16:40 GMT
  878. Organization: Dept. of Computing Science, Umea Univ., 901 87 Umea, Sweden
  879.  
  880. In <busfield.767985832@hurricane> busfield@hurricane.seas.ucla.edu (John D. Busfield) writes:
  881.  
  882. >    Does anyone have an algorithm or code for computing square roots.
  883. >The emphasis is on speed rather than accuracy in that I only need the
  884. >result rounded to the nearest integer (ie sqrt(1000) = 31 or 32).
  885. >Thanks in advance.
  886.  
  887. I posted this to comp.sys.m68k some time ago, here it is again:
  888.  
  889.  
  890. unsigned short ce_quick_sqrt(n)
  891. register unsigned long n;
  892. {
  893.     asm {
  894. ;-------------------------
  895. ;
  896. ; Routine       : ISQRT; integer square root
  897. ; I/O parameters: d0.w = sqrt(d0.l)
  898. ; Registers used: d0-d2/a0
  899. ;
  900. ; This is a highly optimized integer square root routine, based
  901. ; on the iterative Newton/Babylonian method
  902. ;
  903. ;    r(n + 1) = (r(n) + A / R(n)) / 2
  904. ;
  905. ; Verified over the full interval [0x0L,0xFFFFFFFFL]
  906. ;
  907. ; Some minor compromises have been made to make it perform well
  908. ; on the 68000 as well as 68020/030/040. This routine outperforms
  909. ; the best of all other algorithms I've seen (except for a table
  910. ; lookup).
  911. ;
  912. ; Copyright (c) Christer Ericson, 1993. All rights reserved.
  913. ;
  914. ; Christer Ericson, Dept. of Computer Science, University of Umea,
  915. ; S-90187 UMEA, SWEDEN. Internet: christer@cs.umu.se
  916. ;
  917.  
  918. ;-------------------------
  919. ;
  920. ; Macintosh preamble since THINK C passes first register param
  921. ; in d7. Remove this section on any other machine
  922. ;
  923.     move.l    d7,d0
  924. ;-------------------------
  925. ;
  926. ; Actual integer square root routine starts here
  927. ;
  928.     move.l    d0,a0        ; save original input value for the iteration
  929.     beq.s    @exit        ; unfortunately we must special case zero
  930.     moveq    #2,d1        ; init square root guess
  931. ;-------------------------
  932. ;
  933. ; Speed up the process of finding a power of two approximation
  934. ; to the actual square root by shifting an appropriate amount
  935. ; when the input value is large enough
  936. ;
  937. ; If input values are word only, this section can be removed
  938. ;
  939.     move.l    d0,d2
  940.     swap    d2        ; do [and.l 0xFFFF0000,d2] this way to...
  941.     tst.w    d2        ; go faster on 68000 and to avoid having to...
  942.     beq.s    @skip8        ; reload d2 for the next test below
  943.     move.w    #0x200,d1    ; faster than lsl.w #8,d1 (68000)
  944.     lsr.l    #8,d0
  945. @skip8    and.w    #0xFE00,d2    ; this value and shift by 5 are magic
  946.     beq.s    @skip4
  947.     lsl.w    #5,d1
  948.     lsr.l    #5,d0
  949. @skip4
  950.  
  951. ;-------------------------
  952. ;
  953. ; This finds the power of two approximation to the actual square root
  954. ; by doing the integer equivalent to sqrt(x) = 2 ^ (log2(x) / 2). This
  955. ; is done by shifting the input value down while shifting the root
  956. ; approximation value up until they meet in the middle. Better precision
  957. ; (in the step described below) is gained by starting the approximation
  958. ; at 2 instead of 1 (this means that the approximation will be a power
  959. ; of two too large so remember to shift it down).
  960. ;
  961. ; Finally (and here's the clever thing) since, by previously shifting the
  962. ; input value down, it has actually been divided by the root approximation
  963. ; value already so the first iteration is "for free". Not bad, eh?
  964. ;
  965. @loop    add.l    d1,d1
  966.     lsr.l    #1,d0
  967.     cmp.l    d0,d1
  968.     bcs.s    @loop
  969. @skip    lsr.l    #1,d1        ; adjust the approximation
  970.     add.l    d0,d1        ; here we just add and shift to...
  971.     lsr.l    #1,d1        ; get the first iteration "for free"!
  972. ;-------------------------
  973. ;
  974. ; The iterative root value is guaranteed to be larger than (or equal to)
  975. ; the actual square root, except for the initial guess. But since the first
  976. ; iteration was done above, the loop test can be simplified below
  977. ; (Oh, without the bvs.s the routine will fail on most large numbers, like
  978. ; for instance, 0xFFFF0000. Could there be a better way of handling these,
  979. ; so the bvs.s can be removed? Nah...)
  980. ;
  981. @loop2    move.l    a0,d2        ; get original input value
  982.     move.w    d1,d0        ; save current guess
  983.     divu.w    d1,d2        ; do the Newton method thing
  984.     bvs.s    @exit        ; if div overflows, exit with current guess
  985.     add.w    d2,d1
  986.     roxr.w    #1,d1        ; roxr ensures shifting back carry overflow
  987.     cmp.w    d0,d1
  988.     bcs.s    @loop2        ; exit with result in d0.w
  989. @exit
  990.     }
  991. }
  992.  
  993.  
  994. Christer Ericson --- Internet: christer@cs.umu.se --- tel: +46-90-166794
  995. Department of Computer Science, University of Umea, S-90187 UMEA, SWEDEN
  996.  
  997. +++++++++++++++++++++++++++
  998.  
  999. >From usenet@lowry.eche.ualberta.ca (Brian Lowry)
  1000. Date: 4 May 1994 16:38:23 GMT
  1001. Organization: Dept. of Chemical Eng., University of Alberta
  1002.  
  1003. Well, if people are going to start posting square root routines that use
  1004. division, here's about the simplest possible, coded in C:
  1005.  
  1006.  
  1007. #define precLim 1e-8   //for good single precision performance
  1008.  
  1009. float sqrt(float x);
  1010.  
  1011. float sqrt(float x)
  1012. {    register float d = 0.5*(1.0 - x);
  1013.         register float b = 1.0 - d;
  1014.     
  1015.     while ((d > precLim)||(d < precLim))
  1016.     {    d *= 0.5*d/b; b -= d;}
  1017.  
  1018.     return b;
  1019. }
  1020.  
  1021.  
  1022.   This takes about three to five iterations, but on the PowerPC that
  1023. amounts to a whopping 100 to 170 clock cycles.  Since that's enough cycles
  1024. for about 80 multiplies and/or flops, division is definitely not the best
  1025. route here (though it's certainly compact...)
  1026.  
  1027. Brian Lowry
  1028.  
  1029. +++++++++++++++++++++++++++
  1030.  
  1031. >From parkb@bigbang.Stanford.EDU (Brian Park)
  1032. Date: 4 May 1994 20:43:37 GMT
  1033. Organization: Stanford University
  1034.  
  1035. I am assuming that the original poster wanted integer in/ integer out
  1036. since he only wanted accurary within 1.
  1037.  
  1038. The following is a description of code which follows at the end of this
  1039. article.
  1040.  
  1041. lsqrt2() - traditional Newton's method
  1042. - ------
  1043. The traditional Newton's method of getting y = sqrt(n), coded as lsqrt2()
  1044. below)
  1045.  
  1046.     n = y^2
  1047.     y(0) = n
  1048.     y(i+1) = (y(i) + n/y(i))/2
  1049.  
  1050. is second-order convergent, meaning that the relative error in the i+1
  1051. iteration is proportional to the square of the previous error
  1052. (remember, at sufficiently large iteration, relative error << 1).  [Do
  1053. a Taylor series exansion to verify that the first order term
  1054. vanishes].  Hence, for a fixed tolerance, in this case, within unity
  1055. (ie. error of 1/n), the algorithm performs a bisection on the
  1056. error at every iteration.
  1057.  
  1058. My point is that Newton's method is O(log_2(n)) and you are not going
  1059. to do much better than that.  Binary lookup tables are O(log_2(n)) 
  1060. efficient.  The only thing you might save is an integer division
  1061. compared to the Newton's method (see n/y(i) above).  But it also globbles
  1062. up memory and has fixed size.  A hash table provides the fastest
  1063. lookup table, but it takes up even more memory than the binary lookup
  1064. table, and coding it can be more tricky.  Do you really want to use up
  1065. that much memory for a simple square root function?
  1066.  
  1067. I should add that Newton's method is guaranteed to converge for all n.
  1068.  
  1069. lsqrt1() - bit-shift method
  1070. - -----
  1071. There is yet another method (see lsqrt1() function below) that I dreamed
  1072. up last night, and coded it quickly this morning.  It uses bit-shifts
  1073. to perform an integer square root by taking log_2(n), dividing it
  1074. by 2 (hence doing a square root) and shifting it back.  This routine is
  1075. also O(log_2(n)) but has the peculiar property that it is _faster_
  1076. for larger numbers.  You can see why below.  It has the disadvantage that
  1077. it is quite inaccurate for small numbers, but surprisingly accurate for 
  1078. large numbers.
  1079.  
  1080. lsqrt3() - combination
  1081. - ------
  1082. If you really need accurary within unity, then you can plug the result
  1083. of the bit-shift method, lsqrt1(), use it as the initial guess for
  1084. the Newton's method and converge the answer down to its limiting
  1085. accurary.  This combination is really really fast, since Newton's
  1086. method converges within an iteration or two when the initial guess is
  1087. very close to the actual answer.  This has been coded as lsqrt3()
  1088. below.
  1089.  
  1090. For comparision, the straight Newton's method takes longer
  1091. because its initial guess is simply the original answer, n.
  1092. But let me empasize that even with straight Newton's method is O(log_2(n)),
  1093. Sqrt(10^9) takes only 19 iterations, as you can verify.  That's only 19
  1094. integer divisions.  How fast do you want your square root to be?
  1095.  
  1096. I have even more ideas on how to speed things up, but I think the code
  1097. below should get you going.  I'm sorry it's not coded in Macintosh,
  1098. I'm on the Unix box right now, and my mac's at home.  It hasn't
  1099. been tested extensively on the boundary points (ie. 0,1, 2^32-1), 
  1100. but you can do that.
  1101.  
  1102. My final comment concerns the O(sqrt(n)) algorithm that was posted
  1103. a short while ago.  Although it is simple and cute, I would not recommend
  1104. it when you have so many O(log_2(n)) routines to choose from.
  1105.  
  1106. Regards,
  1107. Brian Park
  1108.  
  1109. - - cut for code below ---
  1110.  
  1111. #include <stdio.h>
  1112.  
  1113. #define BITSIZE (sizeof(unsigned long)*8)
  1114.  
  1115. unsigned long lsqrtng();
  1116. unsigned long lsqrt1();
  1117. unsigned long lsqrt2();
  1118. unsigned long lsqrt3();
  1119.  
  1120. /***
  1121. Usage: 
  1122.     lsqrt n
  1123.  
  1124. Example:
  1125.  
  1126. lsqrt 100000
  1127. l = 1000000
  1128. bit shift: 976
  1129. iter = 13
  1130. newton: 1000
  1131. iter = 2
  1132. bit shift + newton: 1000
  1133. ***/
  1134. main(int argc, char **argv)
  1135. {
  1136.     unsigned long l;
  1137.  
  1138.     l = atol(argv[1]);
  1139.     printf("l = %lu\n", l);
  1140.  
  1141.     printf("bit shift: %lu\n", lsqrt1(l));
  1142.     printf("newton: %lu\n", lsqrt2(l));
  1143.     printf("bit shift + newton: %lu\n", lsqrt3(l));
  1144. }
  1145.  
  1146. /***
  1147. Take square root by performing bit-shifts, getting the log_2(a),
  1148. dividing by 2, and shifting back.
  1149. ***/
  1150. unsigned long lsqrt1(unsigned long a)
  1151. {
  1152.     register unsigned int i;
  1153.     register unsigned long l = a;
  1154.  
  1155.     if (a==0) return 0;
  1156.  
  1157.     for (i=0; l<(unsigned long)(1L<<(BITSIZE-1)) && i<BITSIZE; ++i)
  1158.         l<<=1;
  1159.  
  1160.     i = (32-i)>>1;
  1161.     a >>= i;
  1162.     return a;
  1163. }
  1164.  
  1165. /***
  1166. Take square root by using Newton's method with an initial guess of itself.
  1167. ***/
  1168. unsigned long lsqrt2(unsigned long a)
  1169. {
  1170.     return lsqrtng(a, a);
  1171. }
  1172.  
  1173. /***
  1174. Newton's method with guess.
  1175. Newton's method is second order convergence, hence it should be very fast.
  1176. ***/
  1177. unsigned long lsqrtng(register unsigned long a, unsigned long guess)
  1178. {
  1179.     register unsigned long b, b0;
  1180.     int i = 0;
  1181.  
  1182.     if (a == 0) return 0;
  1183.  
  1184.     b = guess;
  1185.     b0 = a/b;
  1186.     while (labs(b-b0)>1) {
  1187.         /* printf("guess = %lu\n", b);*/
  1188.         ++i;
  1189.         b0 = b;
  1190.         b=(a/b+b)>>1;
  1191.     }
  1192.     printf("iter = %d\n", i);
  1193.     return b;
  1194. }
  1195.  
  1196. /***
  1197. Combination Newton's method and bit-shifts.
  1198. ***/
  1199. unsigned long lsqrt3(unsigned long a)
  1200. {
  1201.     return lsqrtng(a, lsqrt1(a));
  1202. }
  1203.  
  1204. +++++++++++++++++++++++++++
  1205.  
  1206. >From sparent@mv.us.adobe.com (Sean Parent)
  1207. Date: Wed, 4 May 1994 20:46:30 GMT
  1208. Organization: Adobe Systems Incorporated
  1209.  
  1210. In article <9405032056.AA35937@geweke.ppp.msu.edu>,
  1211. gewekean@studentg.msu.edu (Andrew Geweke) wrote:
  1212.  
  1213. > Actually, I once found this algorithm:
  1214. > int intSqrt (int num) {
  1215. >    for (i = j = 1, k = 3; num > j; j += (k+=2), ++i)
  1216. >           ;
  1217. >    return i;
  1218. > }
  1219.  
  1220. This is a difference algorithim and similar algorithms can be used to solve
  1221. most any polynomial expression. This is the method used by Charles Babage
  1222. (sp?) in the late 1800's in his difference engine. For example: y = x^3 can
  1223. be calculated over a range with a given step in x of n by:
  1224.  
  1225. y = y` + a
  1226.  
  1227. Where a = (x + n)^3 - x^3. Or a = 3nx^2 + 3xn^2 + n^3.
  1228.  
  1229. The x^2 term (i) can be similary reduce:
  1230. i = i` + b
  1231. Where b = (x + n)^2 - x^2. Or b = 2xn + n^2.
  1232.  
  1233. Finaly the x term is reduced as:
  1234. x = x` + n
  1235.  
  1236. This can be coded up as a loop consisting of only additions. As to the
  1237. original question. To calculate a square root of an integer on a Mac, I
  1238. would code it as:
  1239.  
  1240. inline long LongSqrt(long x)
  1241. {
  1242.   return FracSqrt(x) >> 15;
  1243. }
  1244.  
  1245. FracSqrt is in FixMath.h. This works because squaring a fixed point number
  1246. doubles the number of fractional bits (so a number of type Fract, which is
  1247. 2d30 multiplied by a Fract would yield a 4d60 number). Taking the square
  1248. root of a number then halves the number of bits (to the original
  1249. precision). So a strait square root of a fract would yield a 1d15 value.
  1250. Apple's FracSqrt return a Fract so in effect it is calculating sqrt(x) <<
  1251. 15 [with the bits shifted in actually being calculated]. So if you want a
  1252. number of type Fixed as a result for the sqrt of an integer you could use.
  1253.  
  1254. inline Fixed FixedSqrtLong(long x)
  1255. {
  1256.      return FracSqrt(x) << 1;  // 0/2 + 15 + 1 = 16
  1257. }
  1258.  
  1259. Or a the sqrt of a Fixed yielding a fixed is:
  1260.  
  1261. inline Fixed FixedSqrt(Fixed x)
  1262. {
  1263.   return FracSqrt(x) >> 7; // 16/2 + 15 - 7 = 16
  1264. }
  1265.  
  1266. This is a difficult thing to explain, I don't no of any good terminology
  1267. for talking about fixed point numbers. Play with it some and it will make
  1268. sense.
  1269.  
  1270. -- 
  1271. Sean Parent
  1272.  
  1273. +++++++++++++++++++++++++++
  1274.  
  1275. >From jimc@tau-ceti.isc-br.com (Jim Cathey)
  1276. Date: Wed, 4 May 1994 18:04:33 GMT
  1277. Organization: Olivetti North America, Spokane, WA
  1278.  
  1279. In article <busfield.767985832@hurricane> busfield@hurricane.seas.ucla.edu (John D. Busfield) writes:
  1280. >    Does anyone have an algorithm or code for computing square roots.
  1281. >The emphasis is on speed rather than accuracy in that I only need the
  1282. >result rounded to the nearest integer (ie sqrt(1000) = 31 or 32).
  1283.  
  1284. Here's two:  A Newton's Method, and a cool bit-banger that's a little
  1285. faster under certain circumstances.  (Timings were all on a 68000
  1286. as these are kinda old.  Re-test to see what works best now.)
  1287.  
  1288. *************************************************************************
  1289. *                                                                       *
  1290. *       Integer Square Root (32 to 16 bit).                             *
  1291. *                                                                       *
  1292. *       (Newton-Raphson method).                                        *
  1293. *                                                                       *
  1294. *       Call with:                                                      *
  1295. *               D0.L = Unsigned number.                                 *
  1296. *                                                                       *
  1297. *       Returns:                                                        *
  1298. *               D0.L = SQRT(D0.L)                                       *
  1299. *                                                                       *
  1300. *       Notes:  Result fits in D0.W, but is valid in longword.          *
  1301. *               Takes from 338 cycles (1 shift, 1 division) to          *
  1302. *               1580 cycles (16 shifts, 4 divisions)  (including rts).  *
  1303. *               Averages 854 cycles measured over first 65535 roots.    *
  1304. *               Averages 992 cycles measured over first 500000 roots.   *
  1305. *                                                                       *
  1306. *************************************************************************
  1307.  
  1308.         .globl lsqrt
  1309. *                       Cycles
  1310. lsqrt   movem.l d1-d2,-(sp) (24)
  1311.         move.l d0,d1    (4)     ; Set up for guessing algorithm.
  1312.         beq.s return    (10/8)  ; Don't process zero.
  1313.         moveq #1,d2     (4)
  1314.  
  1315. guess   cmp.l d2,d1     (6)     ; Get a guess that is guaranteed to be
  1316.         bls.s newton    (10/8)  ; too high, but not by much, by dividing the
  1317.         add.l d2,d2     (8)     ; argument by two and multiplying a 1 by 2
  1318.         lsr.l #1,d1     (10)    ; until the power of two passes the modified
  1319.         bra.s guess     (10)    ; argument, then average these two numbers.
  1320.  
  1321. newton  add.l d1,d2     (8)     ; Average the two guesses.
  1322.         lsr.l #1,d2     (10)
  1323.         move.l d0,d1    (4)     ; Generate the next approximation(s)
  1324.         divu d2,d1      (140)   ; via the Newton-Raphson method.
  1325.         bvs.s done      (10/8)  ; Handle out-of-range input (cheats!)
  1326.         cmp.w d1,d2     (4)     ; Have we converged?
  1327.         bls.s done      (10/8)
  1328.         swap d1         (4)     ; No, kill the remainder so the
  1329.         clr.w d1        (4)     ; next average comes out right.
  1330.         swap d1         (4)
  1331.         bra.s newton    (10)
  1332.  
  1333. done    clr.w d0        (4)     ; Return a word answer in a longword.
  1334.         swap d0         (4)
  1335.         move.w d2,d0    (4)
  1336. return  movem.l (sp)+,d1-d2  (28)
  1337.         rts             (16)
  1338.  
  1339.         end
  1340. *************************************************************************
  1341. *                                                                       *
  1342. *       Integer Square Root (32 to 16 bit).                             *
  1343. *                                                                       *
  1344. *       (Exact method, not approximate).                                *
  1345. *                                                                       *
  1346. *       Call with:                                                      *
  1347. *               D0.L = Unsigned number.                                 *
  1348. *                                                                       *
  1349. *       Returns:                                                        *
  1350. *               D0.L = SQRT(D0.L)                                       *
  1351. *                                                                       *
  1352. *       Notes:  Result fits in D0.W, but is valid in longword.          *
  1353. *               Takes from 122 to 1272 cycles (including rts).          *
  1354. *               Averages 610 cycles measured over first 65535 roots.    *
  1355. *               Averages 1104 cycles measured over first 500000 roots.  *
  1356. *                                                                       *
  1357. *************************************************************************
  1358.  
  1359.         .globl lsqrt
  1360. *                       Cycles
  1361. lsqrt   tst.l d0        (4)     ; Skip doing zero.
  1362.         beq.s done      (10/8)
  1363.         cmp.l #$10000,d0 (14)   ; If is a longword, use the long routine.
  1364.         bhs.s glsqrt    (10/8)
  1365.         cmp.w #625,d0   (8)     ; Would the short word routine be quicker?
  1366.         bhi.s gsqrt     (10/8)  ; No, use general purpose word routine.
  1367. *                               ; Otherwise fall into special routine.
  1368. *
  1369. *  For speed, we use three exit points.
  1370. *  This is cheesy, but this is a speed-optimized subroutine!
  1371.  
  1372.         page
  1373. *************************************************************************
  1374. *                                                                       *
  1375. *       Faster Integer Square Root (16 to 8 bit).  For small arguments. *
  1376. *                                                                       *
  1377. *       (Exact method, not approximate).                                *
  1378. *                                                                       *
  1379. *       Call with:                                                      *
  1380. *               D0.W = Unsigned number.                                 *
  1381. *                                                                       *
  1382. *       Returns:                                                        *
  1383. *               D0.W = SQRT(D0.W)                                       *
  1384. *                                                                       *
  1385. *       Notes:  Result fits in D0.B, but is valid in word.              *
  1386. *               Takes from 72 (d0=1) to 504 (d0=625) cycles             *
  1387. *               (including rts).                                        *
  1388. *                                                                       *
  1389. *       Algorithm supplied by Motorola.                                 *
  1390. *                                                                       *
  1391. *************************************************************************
  1392.  
  1393. * Use the theorem that a perfect square is the sum of the first
  1394. * sqrt(arg) number of odd integers.
  1395.  
  1396. *                       Cycles
  1397.         move.w d1,-(sp) (8)
  1398.         move.w #-1,d1   (8)
  1399. qsqrt1  addq.w #2,d1    (4)
  1400.         sub.w d1,d0     (4)
  1401.         bpl qsqrt1      (10/8)
  1402.         asr.w #1,d1     (8)
  1403.         move.w d1,d0    (4)
  1404.         move.w (sp)+,d1 (12)
  1405. done    rts             (16)
  1406.  
  1407.         page
  1408. *************************************************************************
  1409. *                                                                       *
  1410. *       Integer Square Root (16 to 8 bit).                              *
  1411. *                                                                       *
  1412. *       (Exact method, not approximate).                                *
  1413. *                                                                       *
  1414. *       Call with:                                                      *
  1415. *               D0.W = Unsigned number.                                 *
  1416. *                                                                       *
  1417. *       Returns:                                                        *
  1418. *               D0.L = SQRT(D0.W)                                       *
  1419. *                                                                       *
  1420. *       Uses:   D1-D4 as temporaries --                                 *
  1421. *               D1 = Error term;                                        *
  1422. *               D2 = Running estimate;                                  *
  1423. *               D3 = High bracket;                                      *
  1424. *               D4 = Loop counter.                                      *
  1425. *                                                                       *
  1426. *       Notes:  Result fits in D0.B, but is valid in word.              *
  1427. *                                                                       *
  1428. *               Takes from 544 to 624 cycles (including rts).           *
  1429. *                                                                       *
  1430. *               Instruction times for branch-type instructions          *
  1431. *               listed as (X/Y) are for (taken/not taken).              *
  1432. *                                                                       *
  1433. *************************************************************************
  1434.  
  1435. *                       Cycles
  1436. gsqrt   movem.l d1-d4,-(sp) (40)
  1437.         move.w #7,d4    (8)     ; Loop count (bits-1 of result).
  1438.         clr.w d1        (4)     ; Error term in D1.
  1439.         clr.w d2        (4)
  1440. sqrt1   add.w d0,d0     (4)     ; Get 2 leading bits a time and add
  1441.         addx.w d1,d1    (4)     ; into Error term for interpolation.
  1442.         add.w d0,d0     (4)     ; (Classical method, easy in binary).
  1443.         addx.w d1,d1    (4)
  1444.         add.w d2,d2     (4)     ; Running estimate * 2.
  1445.         move.w d2,d3    (4)
  1446.         add.w d3,d3     (4)
  1447.         cmp.w d3,d1     (4)
  1448.         bls.s sqrt2     (10/8)  ; New Error term > 2* Running estimate?
  1449.         addq.w #1,d2    (4)     ; Yes, we want a '1' bit then.
  1450.         addq.w #1,d3    (4)     ; Fix up new Error term.
  1451.         sub.w d3,d1     (4)
  1452. sqrt2   dbra d4,sqrt1   (10/14) ; Do all 8 bit-pairs.
  1453.         move.w d2,d0    (4)
  1454.         movem.l (sp)+,d1-d4 (44)
  1455.         rts             (16)
  1456.  
  1457.         page
  1458. *************************************************************************
  1459. *                                                                       *
  1460. *       Integer Square Root (32 to 16 bit).                             *
  1461. *                                                                       *
  1462. *       (Exact method, not approximate).                                *
  1463. *                                                                       *
  1464. *       Call with:                                                      *
  1465. *               D0.L = Unsigned number.                                 *
  1466. *                                                                       *
  1467. *       Returns:                                                        *
  1468. *               D0.L = SQRT(D0.L)                                       *
  1469. *                                                                       *
  1470. *       Uses:   D1-D4 as temporaries --                                 *
  1471. *               D1 = Error term;                                        *
  1472. *               D2 = Running estimate;                                  *
  1473. *               D3 = High bracket;                                      *
  1474. *               D4 = Loop counter.                                      *
  1475. *                                                                       *
  1476. *       Notes:  Result fits in D0.W, but is valid in longword.          *
  1477. *                                                                       *
  1478. *               Takes from 1080 to 1236 cycles (including rts.)         *
  1479. *                                                                       *
  1480. *               Two of the 16 passes are unrolled from the loop so that *
  1481. *               quicker instructions may be used where there is no      *
  1482. *               danger of overflow (in the early passes).               *
  1483. *                                                                       *
  1484. *               Instruction times for branch-type instructions          *
  1485. *               listed as (X/Y) are for (taken/not taken).              *
  1486. *                                                                       *
  1487. *************************************************************************
  1488.  
  1489. *                       Cycles
  1490. glsqrt  movem.l d1-d4,-(sp) (40)
  1491.         moveq #13,d4    (4)     ; Loop count (bits-1 of result).
  1492.         moveq #0,d1     (4)     ; Error term in D1.
  1493.         moveq #0,d2     (4)
  1494. lsqrt1  add.l d0,d0     (8)     ; Get 2 leading bits a time and add
  1495.         addx.w d1,d1    (4)     ; into Error term for interpolation.
  1496.         add.l d0,d0     (8)     ; (Classical method, easy in binary).
  1497.         addx.w d1,d1    (4)
  1498.         add.w d2,d2     (4)     ; Running estimate * 2.
  1499.         move.w d2,d3    (4)
  1500.         add.w d3,d3     (4)
  1501.         cmp.w d3,d1     (4)
  1502.         bls.s lsqrt2    (10/8)  ; New Error term > 2* Running estimate?
  1503.         addq.w #1,d2    (4)     ; Yes, we want a '1' bit then.
  1504.         addq.w #1,d3    (4)     ; Fix up new Error term.
  1505.         sub.w d3,d1     (4)
  1506. lsqrt2  dbra d4,lsqrt1  (10/14) ; Do first 14 bit-pairs.
  1507.  
  1508.         add.l d0,d0     (8)     ; Do 15-th bit-pair.
  1509.         addx.w d1,d1    (4)
  1510.         add.l d0,d0     (8)
  1511.         addx.l d1,d1    (8)
  1512.         add.w d2,d2     (4)
  1513.         move.l d2,d3    (4)
  1514.         add.w d3,d3     (4)
  1515.         cmp.l d3,d1     (6)
  1516.         bls.s lsqrt3    (10/8)
  1517.         addq.w #1,d2    (4)
  1518.         addq.w #1,d3    (4)
  1519.         sub.l d3,d1     (8)
  1520.  
  1521. lsqrt3  add.l d0,d0     (8)     ; Do 16-th bit-pair.
  1522.         addx.l d1,d1    (8)
  1523.         add.l d0,d0     (8)
  1524.         addx.l d1,d1    (8)
  1525.         add.w d2,d2     (4)
  1526.         move.l d2,d3    (4)
  1527.         add.l d3,d3     (8)
  1528.         cmp.l d3,d1     (6)
  1529.         bls.s lsqrt4    (10/8)
  1530.         addq.w #1,d2    (4)
  1531. lsqrt4  move.w d2,d0    (4)
  1532.         movem.l (sp)+,d1-d4 (44)
  1533.         rts             (16)
  1534.  
  1535.         end
  1536. -- 
  1537. +----------------+
  1538. ! II      CCCCCC !  Jim Cathey
  1539. ! II  SSSSCC     !  ISC-Bunker Ramo
  1540. ! II      CC     !  TAF-C8;  Spokane, WA  99220
  1541. ! IISSSS  CC     !  UUCP: uunet!isc-br!jimc (jimc@isc-br.isc-br.com)
  1542. ! II      CCCCCC !  (509) 927-5757
  1543.  
  1544. +++++++++++++++++++++++++++
  1545.  
  1546. >From lasley@umdsp.umd.edu (Scott E. Lasley)
  1547. Date: Wed,  4 May 1994 20:25:02 -0400
  1548. Organization: Space Physics Group, University of Maryland
  1549.  
  1550. In article <rmah-030594174155@rmah.dialup.access.net>, rmah@panix.com (Robert 
  1551. S. Mah) writes:
  1552. > There is an article on generating very fast square root aproximations 
  1553. > in the book "Graphics Gems", Ed. Glassner. 
  1554. >  
  1555. > It generates a lookup table which is indexed by munging the exponent 
  1556. > of the argument and then uses the mantissa to do an (linear?) 
  1557. > aproximation to the final result.  It's fairly accurate to within a 
  1558. > few decimal points.  I think the source code is also available 
  1559. > somewhere on the net, but I'm afraid I don't know where. 
  1560.  
  1561. some (perhaps all) of the code in the Graphics Gems series of books can be
  1562. found at ftp.princeton.edu.  here is a URL
  1563.  
  1564. ftp://ftp.princeton.edu//pub/Graphics/GraphicsGems
  1565.  
  1566. there are directories for books I through IV. the ReadMe file in the 
  1567. GemsIII directory contains the following line:
  1568.  
  1569.     sqrt.c        II.1    Steve Hill, "IEEE Fast Square Root"
  1570.  
  1571. hope this helps,
  1572.  
  1573.  
  1574. lasley@umdsp.umd.edu
  1575. "... and there were bumper stickers saying "Free Love"
  1576.  like it was some kind of political prisoner..."  David Wilcox
  1577.  
  1578.  
  1579. +++++++++++++++++++++++++++
  1580.  
  1581. >From nagle@netcom.com (John Nagle)
  1582. Date: Thu, 5 May 1994 02:23:34 GMT
  1583. Organization: NETCOM On-line Communication Services (408 241-9760 guest)
  1584.  
  1585. busfield@hurricane.seas.ucla.edu (John D. Busfield) writes:
  1586. >    Does anyone have an algorithm or code for computing square roots.
  1587. >The emphasis is on speed rather than accuracy in that I only need the
  1588. >result rounded to the nearest integer (ie sqrt(1000) = 31 or 32).
  1589. >Thanks in advance.
  1590.  
  1591.      The classic for floating point is to check the exponent and if odd,
  1592. shift the mantissa right one bit.  Then halve the exponent.  Use the
  1593. high 4 bits of the mantissa to select a starting mantissa from a table of
  1594. 16 values.  Then execute Newton's Method for two or three iterations,
  1595. written out in line.  On a machine with an FPU, this beats most iterative
  1596. methods.  Try it on a PPC.  This may actually be faster than an 
  1597. iterative integer method.
  1598.  
  1599.                     John Nagle
  1600.  
  1601. +++++++++++++++++++++++++++
  1602.  
  1603. >From Ron_Hunsinger@bmug.org (Ron Hunsinger)
  1604. Date: Thu,  5 May 94 05:35:48 PST
  1605. Organization: Berkeley Macintosh Users Group
  1606.  
  1607. parkb@bigbang.Stanford.EDU (Brian Park) writes:
  1608.  
  1609. >lsqrt2() - traditional Newton's method
  1610. >--------
  1611. >The traditional Newton's method of getting y = sqrt(n), coded as lsqrt2()
  1612. >below)
  1613. >
  1614. >n = y^2
  1615. >y(0) = n
  1616. >y(i+1) = (y(i) + n/y(i))/2
  1617. >
  1618. >is second-order convergent, 
  1619.  
  1620. You can do square root much faster than this.  Square root is about as
  1621. complex, and takes about as much time, as a divide.  A square root is
  1622. like a division in which the quotient and divisor are equal.
  1623. The usual division algorithm knows the divisor from the beginning, and
  1624. discovers the quotient a bit at a time.  You just have to tweak the
  1625. algorithm a little so that it discovers the divisor and quotient in
  1626. parallel, a bit at a time.
  1627.  
  1628. Think about how you would calculate square root by hand.  Then try
  1629. to do it in binary.  Notice how easy it becomes.
  1630.  
  1631. >My point is that Newton's method is O(log_2(n)) and you are not going
  1632. >to do much better than that.  
  1633.  
  1634. Newton's method is O(log n) ITERATIONS, but you do a divide in each 
  1635. iteration.  If division takes O(log n) shift-subtracts, then you have
  1636. a run time of O((log n)^2) shift-subtracts, compared to only O(log n)
  1637. shift-subtracts using a modified divide algorithm.
  1638.  
  1639. [Not that it really matters.  You aren't writing an arbitrary-precision
  1640. square root routine.  You have a fixed upper bound on the size of the
  1641. input, and ANY operation with only a finite number of valid inputs
  1642. can be implemented in O(1) time.]
  1643.  
  1644. [And if you have a very fast divide, as fast as a shift-subtract, as
  1645. might happen if you use a hardware divide instruction on a RISC computer,
  1646. then both methods might have nearly the same speed.  But if shifting
  1647. is faster than division, Newton's method is going to lose.]
  1648.  
  1649. -Ron Hunsinger
  1650.  
  1651. +++++++++++++++++++++++++++
  1652.  
  1653. >From afcjlloyd@aol.com (AFC JLloyd)
  1654. Date: 5 May 1994 12:37:02 -0400
  1655. Organization: America Online, Inc. (1-800-827-6364)
  1656.  
  1657. In article <2q91dp$rf@nntp2.Stanford.EDU>, parkb@bigbang.Stanford.EDU (Brian
  1658. Park) writes:
  1659.  
  1660. >>>
  1661. But let me empasize that even with straight Newton's method is O(log_2(n)),
  1662. Sqrt(10^9) takes only 19 iterations, as you can verify.  That's only 19
  1663. integer divisions.  How fast do you want your square root to be?
  1664. <<<
  1665.  
  1666. If you simply provide a better starting estimate you can reduce your 19
  1667. iterations
  1668. down to a maximum of 5.  A very cheap way to provide a better estimate is to
  1669. find the most significant bit and use it to estimate log2(N) and thus sqrt(N).
  1670. I don't know about you, but when I want fast code I'll take a factor of four
  1671. anyway I can get. 
  1672.  
  1673. However, if you're really out for speed, it turns out that Newton's
  1674. method is not the best.  Yesterday,  
  1675. pottier@corvette.ens.fr (Francois Pottier) posted an algorithm
  1676. by (Dr.) John Bruner,   bruner@csrd.uiuc.edu:
  1677.  
  1678. >>>>
  1679. unsigned int isqrt(unsigned long x)
  1680. {
  1681.  unsigned long r, nr, m;
  1682.  
  1683.  r = 0;
  1684.  m = 0x40000000;
  1685.  do {
  1686.   nr = r + m;
  1687.   if (nr <= x) {
  1688.    x -= nr;
  1689.    r = nr + m;
  1690.   }
  1691.   r >>= 1;
  1692.   m >>= 2;
  1693.  } while (m != 0);
  1694.  
  1695.  return(r);
  1696. }
  1697. <<<<
  1698.  
  1699. (I've removed two lines of code that round the result up if
  1700. rounding to nearest integer is desired).
  1701. This is an incredibly great algorithm, which uses exactly
  1702. 16 iterations but no integer multiply or divides.
  1703.  
  1704. However,  if you really want the fastest possible code, 
  1705. you should rewrite it like this:
  1706.  
  1707. unsigned short isqrt(register unsigned long x)
  1708. {
  1709.  register unsigned long r;
  1710.  register unsigned long nr;
  1711.  register unsigned long m;
  1712.  
  1713.  r = 0;
  1714.  m = 0x40000000;
  1715.   nr = m;       if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1716.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1717.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1718.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1719.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1720.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1721.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1722.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1723.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1724.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1725.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1726.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1727.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1728.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1729.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1; m >>= 2;
  1730.   nr = r + m; if (nr <= x) { x -= nr; r = nr + m; } r >>= 1;
  1731.  
  1732.   return(r);
  1733. }
  1734.  
  1735. This code is 40% faster (on my 840av) than code that I have been 
  1736. using that used 4 iterations of Newton-Raphson after seeding 
  1737. along the lines I mentioned above.
  1738.  
  1739. It may be possible to speed this up even further by using the
  1740. fast estimate of Log2(N) to reduce the number of iterations
  1741. from 16 to the absolute minimum (ceil(Log2(N)/2), though
  1742. I expect the improvement to be minimal since each iteration of
  1743. this algorithm is so cheap.
  1744.  
  1745. Jim Lloyd
  1746. afcjlloyd@aol.com
  1747.  
  1748.  
  1749. +++++++++++++++++++++++++++
  1750.  
  1751. >From trussler@panix.com (Tom Russler)
  1752. Date: Fri, 06 May 1994 00:38:31 -0400
  1753. Organization: PANIX Public Access Internet and UNIX (NYC)
  1754.  
  1755.  busfield@hurricane.seas.ucla.edu (John D. Busfield) writes:
  1756.  >    Does anyone have an algorithm or code for computing square roots.
  1757.  >The emphasis is on speed rather than accuracy in that I only need the
  1758.  >result rounded to the nearest integer (ie sqrt(1000) = 31 or 32).
  1759.  >Thanks in advance.
  1760.  
  1761. In 68000 assembly in THINK C:
  1762.  
  1763.              move.l     number, d0
  1764.              move.l     #1, d1
  1765.              move.l     d0, d2
  1766.       @1     cmp.l      d1, d2
  1767.              ble           @2
  1768.              lsl.l      #1, d1
  1769.              lsr.l      #1, d2
  1770.              bra           @1
  1771.       @2     add.l      d2, d1
  1772.              lsr.l   #1, d1
  1773.              divu       d1, d0
  1774.              add.w      d1, d0
  1775.              add.w      #1, d0
  1776.              lsr.w      #1, d0
  1777.  
  1778. -- 
  1779. Tom Russler
  1780. trussler@panix.com
  1781.  
  1782. +++++++++++++++++++++++++++
  1783.  
  1784. >From zstern@adobe.com (Zalman Stern)
  1785. Date: Fri, 6 May 1994 04:35:37 GMT
  1786. Organization: Adobe Systems Incorporated
  1787.  
  1788. Ron_Hunsinger@bmug.org (Ron Hunsinger) writes
  1789. > [And if you have a very fast divide, as fast as a shift-subtract, as
  1790. > might happen if you use a hardware divide instruction on a RISC computer,
  1791.  
  1792. This is not even close to true for any RISC implementation I know of. If the  
  1793. divisor is loop-invariant, one can multiply by the reciprocal which may be a  
  1794. single cycle operation, however this is not the case in the example being  
  1795. discussed. Most RISC architecture now include a floating-point square root  
  1796. instruction. This is partially due to this operations similarity to division  
  1797. (i.e. can use the same hardware) and partially due to its common appearance  
  1798. in electrical CAD codes :-)
  1799.  
  1800. I believe the integer square root routine I use is based on the algorithm  
  1801. Ron referred to. It has the following comment at the top (thanks to Mark  
  1802. Hamburg):
  1803.  
  1804. /*
  1805.  *      A square-root routine.  See Dijkstra, "A Discipline of Programming",
  1806.  *      page 65.
  1807.  */
  1808.  
  1809. I threw in an optimization to use the PowerPC count-leading-zeros  
  1810. instruction to efficiently reduce the number of iterations. (There is a  
  1811. similar instruction on the 68K.) The result is competitive with a lookup  
  1812. table based method for computing sqrt(x^2 + y^2) that uses a divide. (I'd  
  1813. post the code, but I didn't write it and I'm sure Adobe would frown on my  
  1814. doing so. Besides, reading Dijkstra is good for you :-))
  1815. --
  1816. Zalman Stern           zalman@adobe.com            (415) 962 3824
  1817. Adobe Systems, 1585 Charleston Rd., POB 7900, Mountain View, CA 94039-7900
  1818.           There is no lust like the present.
  1819.  
  1820. +++++++++++++++++++++++++++
  1821.  
  1822. >From hall_j@sat.mot.com (Joseph Hall)
  1823. Date: Thu, 5 May 1994 21:55:49 GMT
  1824. Organization: Motorola Inc., Satellite Communications
  1825.  
  1826. Seems it was nagle@netcom.com (John Nagle) who said:
  1827. >busfield@hurricane.seas.ucla.edu (John D. Busfield) writes:
  1828. >>    Does anyone have an algorithm or code for computing square roots.
  1829. >>The emphasis is on speed rather than accuracy in that I only need the
  1830. >>result rounded to the nearest integer (ie sqrt(1000) = 31 or 32).
  1831. >>Thanks in advance.
  1832. >
  1833. >     The classic for floating point is to check the exponent and if odd,
  1834. >shift the mantissa right one bit.  Then halve the exponent. [...]
  1835.  
  1836. You can consult Plaugher's "The Standard C Library" for a portable
  1837. floating point sqrt.  For a positive real number, the algorithm is:
  1838.  
  1839.   1) separate exponent and mantissa -- basically bit-masking except
  1840.        in cases of gradual underflow
  1841.   2) compute a quadratic least-squares fit to sqrt for the mantissa
  1842.        (y = (-.1984742*x+.8804894)*x + .3176687)
  1843.   3) follow with 3 iterations of Newton's method (y = .5*(y+x/y))
  1844.   4) if exponent is odd, a) multiply mantissa by sqrt(2) and
  1845.                          b) subtract 1 from exponent
  1846.   5) divide exponent by 2
  1847.   6) reassemble exponent and mantissa
  1848.  
  1849. Right-shifting the mantissa for odd exponents before computing
  1850. the root, to eliminate the multiplication by sqrt(2), is harder to 
  1851. express portably, but is certainly possible.  Plaugher doesn't make
  1852. any particular efforts to replace things like ".5 * x" with shifts.
  1853.  
  1854. Handy little book.  ISBN 0-13-131509-9.
  1855.  
  1856. (begin digression)
  1857.  
  1858. Plaugher uses conventional floating-point techniques to compute
  1859. transcendental functions.  This is pretty efficient, and these days
  1860. may be as good as any technique.  However, there are also algorithms
  1861. that allow you to compute trigonometric functions, as well as exponent
  1862. and log, by using only shifts and adds/subtracts--as if you were doing a
  1863. divide.  In fact, the computational effort is just twice that of
  1864. a divide.  I have seen relatively few references to these techniques,
  1865. but they are easy to implement.
  1866.  
  1867. For example, to compute an exponent, you need a table of ln(101(2)),
  1868. ln(11(2)), ln(1(2)), ln(1.1(2)), ln(1.01(2)), ln(1.001(2)), etc.   
  1869. Then you can code a fixed-point version like this (please excuse typos 
  1870. since I can't paste this directly in here at the moment):
  1871.  
  1872.   unsigned long logTbl[] = 
  1873.       { /* binary ln((2^i + 65536)/65536), for i == 32..1), e.g. */
  1874.         0xa65b1, 0x9b441, 0x902d3 ... 
  1875.         /* ln 2147549184/65536, ln 1073807360/65536, ln 536936448/65536 */ };
  1876.  
  1877.   unsigned long fexp(unsigned long x)
  1878.   {
  1879.     long i = 1L, j = 0L, k = 0x10000L, l = 0L, *lt = logTbl - 1;
  1880.     while (i <= 32) {
  1881.       j = l + lt[i];
  1882.       if (j > x) {
  1883.         i++;
  1884.       } else {
  1885.         l = j;
  1886.         k += k >> i;
  1887.       }
  1888.     }
  1889.     return k;
  1890.   }
  1891.  
  1892. This computes the exponent iteratively in k.  The log of the approximation
  1893. is maintained in l.  If l + the current entry in the table is <=
  1894. than the value you are computing the exponent of, then you add the
  1895. log in the table to l, and multiply k by a number that is conveniently
  1896. in the form 1 + some power of 2.  Repeat until the table is exhausted.
  1897.  
  1898. These days this may not be any faster than using the coprocessor.  However,
  1899. this technique was occasionally used to write very high-performance libraries 
  1900. for 8- and early 16-bit processors.  I doubt it was ever used in any
  1901. commercial BASIC, though, because it is not well known, and BASIC would
  1902. have been a hell of a lot faster for numerical work if it had been.  I first
  1903. heard this technique described in the mid 70s, but the literature goes
  1904. back to at least the 60s.
  1905.  
  1906. I wonder if this technique has ever been used to implement transcendental 
  1907. functions in microcode.  At one time I was thinking of trying to get it 
  1908. working on a TI bit slice CPU, that is, build my own coprocessor.  :-)
  1909.  
  1910. -- 
  1911. Joseph Nathan Hall | Joseph's Law of Interface Design: Never give your users
  1912. Software Architect | a choice between the easy way and the right way.
  1913. Gorca Systems Inc. |                 joseph@joebloe.maple-shade.nj.us (home)
  1914. (on assignment)    | (602) 732-2549 (work)  Joseph_Hall-SC052C@email.mot.com
  1915.  
  1916. +++++++++++++++++++++++++++
  1917.  
  1918. >From Ron_Hunsinger@bmug.org (Ron Hunsinger)
  1919. Date: Sat,  7 May 94 13:41:39 PST
  1920. Organization: Berkeley Macintosh Users Group
  1921.  
  1922. parkb@bigbang.Stanford.EDU (Brian Park) writes:
  1923.  
  1924. >But let me empasize that even with straight Newton's method is O(log_2(n)),
  1925. >Sqrt(10^9) takes only 19 iterations, as you can verify.  That's only 19
  1926. >integer divisions.  How fast do you want your square root to be?
  1927.  
  1928. I want it to be as fast as a single integer division.  Why take 19 times
  1929. as long as I have to?
  1930.  
  1931.  
  1932.  
  1933. zstern@adobe.com (Zalman Stern) writes:
  1934.  
  1935. >Ron_Hunsinger@bmug.org (Ron Hunsinger) writes
  1936. >> [And if you have a very fast divide, as fast as a shift-subtract, as
  1937. >> might happen if you use a hardware divide instruction on a RISC computer,
  1938. >
  1939. >This is not even close to true for any RISC implementation I know of. 
  1940.  
  1941. Glad to hear it.  I only included the comment because I did not have
  1942. instruction timings handy, and I was afraid someone was going to come 
  1943. along and say I needn't worry about avoiding divides because on the 
  1944. PowerPC (or some other RISC computer) EVERYTHING, including divide,
  1945. took only a single cycle, and so divide was just as fast as shift.
  1946.  
  1947. I knew shift couldn't be slower than divide, and if it really is faster
  1948. (which is reasonable), then finding a square root algorithm that does
  1949. not do any divides is a worthwhile objective.
  1950.  
  1951. >I believe the integer square root routine I use is based on the algorithm  
  1952. >Ron referred to. It has the following comment at the top (thanks to Mark  
  1953. >Hamburg):
  1954. >
  1955. >/*
  1956. > *      A square-root routine.  See Dijkstra, "A Discipline of Programming",
  1957. > *      page 65.
  1958. > */
  1959.  
  1960. A distinct possibility, since I read all the Dijkstra books I could get
  1961. my hands on, way back when.  However, I knew that square root could be
  1962. done as quickly as division at least as far back as high school, before
  1963. I had ever heard of Dijkstra (or seen a computer for that matter).  As 
  1964. I said, the method suggests itself as soon as you assail to calculate 
  1965. square root using the traditional pencil and paper method in binary.
  1966.  
  1967. >I threw in an optimization to use the PowerPC count-leading-zeros  
  1968. >instruction to efficiently reduce the number of iterations. (There is a  
  1969. >similar instruction on the 68K.) 
  1970.  
  1971. There is?  Is this a 68040 instruction?  I can't find any such instruction
  1972. at least through the 68030.  I thought the 68040 was just a 68030 with
  1973. a bigger cache and a built-in FPU.  Sure would be nice, though.  The
  1974. Unisys A-series computers have a similar instruction, accessible through
  1975. the built-in FIRSTONE function in Burroughs Extended Algol, which I
  1976. found many interesting (and not always obvious) uses for.
  1977.  
  1978. >The result is competitive with a lookup  
  1979. >table based method for computing sqrt(x^2 + y^2) that uses a divide. (I'd  
  1980. >post the code, but I didn't write it and I'm sure Adobe would frown on my  
  1981. >doing so. Besides, reading Dijkstra is good for you :-))
  1982.  
  1983. No problem.  I'll post mine, which I wrote from scratch before checking
  1984. your Dijkstra reference. My routine and his, neither of which uses divides
  1985. (except by 2 or 4), bear only a vague similarity.  (But reading Dijkstra 
  1986. is still good for you.)  The whole thing is as fast as a single divide 
  1987. done by subroutine (as, for example, would be required to divide 32-bit 
  1988. integers on a 68000).
  1989.  
  1990. Normally, a division subroutine will keep the divisor fixed and shift
  1991. the dividend past it, doing subtractions (and incrementing the quotient)
  1992. as needed.  My first thought was to do the same thing, but that's messy
  1993. to do in C.  (In assembler, you would use LSL, ROXL to shift bits out
  1994. of one register into another; but that doesn't map well to C.)  So 
  1995. instead, I keep the dividend fixed, and shift the divisor right.  Just as
  1996. in the pencil and paper square root method, you take the digits (bits) of
  1997. the argument two at a time.  But since the quotient (a.k.a. the square
  1998. root) is accumulating bits one at a time in the opposite direction, it
  1999. ends up only shifting one bit at a time.  
  2000.  
  2001. Without further comment, my version (which is meant to be fast, not 
  2002. necessarily readable) follows:
  2003.  
  2004. #define BITS 32
  2005. // BITS is the smallest even integer such that 2^BITS > ULONG_MAX.
  2006. // If you port this routine to a computer where 2^(BITS-1) > ULONG_MAX
  2007. // (Unisys A-series, for example, where integers would generally be
  2008. // stored in the 39-bit mantissa of a 48-bit word), unwind the first 
  2009. // iteration of the loop, and special-case references to 'half' in that 
  2010. // first iteration so as to avoid overflow.
  2011.  
  2012. unsigned long lsqrt (unsigned long n) {
  2013.     // Compute the integer square root of the integer argument n
  2014.     // Method is to divide n by x computing the quotient x and remainder r
  2015.     // Notice that the divisor x is changing as the quotient x changes
  2016.  
  2017.     // Instead of shifting the dividend/remainder left, we shift the
  2018.     // quotient/divisor right.  The binary point starts at the extreme
  2019.     // left, and shifts two bits at a time to the extreme right.
  2020.  
  2021.     // The residue contains n-x^2.  (Within these comments, the ^ operator
  2022.     // signifies exponentiation rather than exclusive or.  Also, the /
  2023.     // operator returns fractions, rather than truncating, so 1/4 means
  2024.     // one fourth, not zero.)
  2025.  
  2026.     // Since (x + 1/2)^2 == x^2 + x + 1/4,
  2027.     //   n - (x + 1/2)^2 == (n - x^2) - (x + 1/4)
  2028.     // Thus, we can increase x by 1/2 if we decrease (n-x^2) by (x+1/4)
  2029.  
  2030.     unsigned long residue;   // n - x^2
  2031.     unsigned long root;      // x + 1/4
  2032.     unsigned long half;      // 1/2
  2033.  
  2034.     residue = n;             // n - (x = 0)^2, with suitable alignment
  2035.     root = 1 << (BITS - 2);  // x + 1/4, shifted left BITS places
  2036.     half = root + root;      // 1/2, shifted left BITS places
  2037.     
  2038.     do {
  2039.         if (root <= residue) {   // Whenever we can,
  2040.             residue -= root;         // decrease (n-x^2) by (x+1/4)
  2041.             root += half; }          // increase x by 1/2
  2042.         half >>= 2;          // Shift binary point 2 places right
  2043.         root -= half;        // x{+1/2}+1/4 - 1/8 == x{+1/2}+1/8
  2044.         root >>= 1;          // 2x{+1}+1/4, shifted right 2 places
  2045.         } while (half);      // When 1/2 == 0, binary point is at far right
  2046.     
  2047.     // Omit the following line to truncate instead of rounding
  2048.     if (root < residue) ++root;
  2049.     
  2050.     return root;   // Guaranteed to be correctly rounded (or truncated)
  2051.     }
  2052.  
  2053. Enjoy,
  2054. -Ron Hunsinger
  2055.  
  2056. +++++++++++++++++++++++++++
  2057.  
  2058. >From Ron_Hunsinger@bmug.org (Ron Hunsinger)
  2059. Date: Sun,  8 May 94 04:45:40 PST
  2060. Organization: Berkeley Macintosh Users Group
  2061.  
  2062. trussler@panix.com (Tom Russler) writes:
  2063. >
  2064. > busfield@hurricane.seas.ucla.edu (John D. Busfield) writes:
  2065. > >    Does anyone have an algorithm or code for computing square roots.
  2066. > >The emphasis is on speed rather than accuracy in that I only need the
  2067. > >result rounded to the nearest integer (ie sqrt(1000) = 31 or 32).
  2068. > >Thanks in advance.
  2069. >
  2070. >In 68000 assembly in THINK C:
  2071. >
  2072. >     move.l number, d0
  2073. >     move.l #1, d1
  2074. >     move.l d0, d2
  2075. >  @1 cmp.l  d1, d2
  2076. >     ble   @2
  2077. >     lsl.l  #1, d1
  2078. >     lsr.l  #1, d2
  2079. >     bra   @1
  2080. >  @2 add.l  d2, d1
  2081. >     lsr.l   #1, d1
  2082. >     divu   d1, d0
  2083. >     add.w  d1, d0
  2084. >     add.w  #1, d0
  2085. >     lsr.w  #1, d0
  2086.  
  2087. Sorry.  Valiant effort, but no cigar.  You don't handle boundary 
  2088. conditions correctly.  Examine what happens when 'number' is 0xFFFFaaaa, 
  2089. where aaaa is any arbitrary bit pattern.
  2090.  
  2091. >     move.l number, d0     ; d0 = 0xFFFFaaaa
  2092. >     move.l #1, d1         ; d1 = 0x00000001
  2093. >     move.l d0, d2         ; d2 = 0xFFFFaaaa
  2094.  
  2095. >  @1 cmp.l  d1, d2
  2096. >     ble   @2
  2097. >     lsl.l  #1, d1
  2098. >     lsr.l  #1, d2
  2099. >     bra   @1
  2100.  
  2101.        ; after 16 iterations, you break out of the above loop, with:
  2102.                                ; d1 = 0x00010000 = 65536
  2103.                                ; d2 = 0x0000FFFF = 65535
  2104.  
  2105. >  @2 add.l  d2, d1         ; d1 = 0x0001FFFF
  2106. >     lsr.l   #1, d1         ; d1 = 0x0000FFFF = 65535
  2107. >     divu   d1, d0   <-----OVERFLOW:  d0/d1 >= 65536, to big for a short
  2108.  
  2109. In fact, you should have seen that overflow was a problem.  DIVU will
  2110. always overflow, no matter what the divisor, if the dividend is greater
  2111. than 65535*65535 = 0xFFFE0001.
  2112.  
  2113. You may have been counting on the fact that, if overflow is detected,
  2114. the operands are unaffected, but that doesn't help.  The contents of 
  2115. d0.w after the divide is aaaa, which was a completely arbitrary value.
  2116. Continuing:
  2117.  
  2118. >     add.w  d1, d0   <-----OVERFLOW AGAIN:  Since d1=65535, the
  2119. >     add.w  #1, d0         ; effect of these two instruction is to
  2120.                                ; overflow at some point, but otherwise
  2121.                                ; do nothing.  d0 still contains aaaa
  2122.  
  2123. >     lsr.w  #1, d0         ; divide the garbage by 2.
  2124.  
  2125. The final result is in the range 0..32767.  The correct result should
  2126. be 65535 (if aaaa is 0000) or 65536 (for any other value of aaaa).
  2127. Again, you should have seen this coming.  Your final instruction can
  2128. never return a value >32767, meaning that you cannot possibly return
  2129. the correct result for any number > 32767*32768 = 0x3FFF8000.
  2130.  
  2131.  
  2132. You also do not achieve the stated accuracy goal, "I [only] need the
  2133. result rounded to the nearest integer", even when you don't overflow.
  2134.  
  2135. Suppose 'number' = 0x10004000 = 268451840.  Your code computes a value
  2136. of 16794.  The correctly rounded value is 16384.  Off by 410 is not "the
  2137. nearest integer".
  2138.  
  2139. -Ron "who gets very picky sometimes :)" Hunsinger
  2140.  
  2141. +++++++++++++++++++++++++++
  2142.  
  2143. >From fixer@faxcsl.dcrt.nih.gov (Chris Gonna' Find Ray Charles Tate)
  2144. Date: Mon, 9 May 1994 14:04:10 GMT
  2145. Organization: DCRT, NIH, Bethesda, MD
  2146.  
  2147. In article <0014A722.fc@bmug.org>, Ron_Hunsinger@bmug.org (Ron Hunsinger) writes:
  2148. >
  2149. >zstern@adobe.com (Zalman Stern) writes:
  2150. >>
  2151. >>I threw in an optimization to use the PowerPC count-leading-zeros  
  2152. >>instruction to efficiently reduce the number of iterations. (There is a  
  2153. >>similar instruction on the 68K.) 
  2154. >
  2155. >There is?  Is this a 68040 instruction?  I can't find any such instruction
  2156. >at least through the 68030.  I thought the 68040 was just a 68030 with
  2157. >a bigger cache and a built-in FPU.
  2158.  
  2159. I think you're looking for the BFFFO instruction, which my 680x0 family
  2160. reference describes as "Find First One in Bit Field," and says it's
  2161. a 60820 instruction (and later, of course).
  2162.  
  2163. The book I'm looking in is Motorola's "M68000 Family Programmer's
  2164. Reference Manual," which doesn't seem to have any Library of Congress
  2165. registration (!), but which is Motorola part number M68000PM/AD.
  2166.  
  2167. - -------------------------------------------------------------
  2168. Christopher Tate             |  "So he dropped the heart - 
  2169. MSD, Inc.                    |     the floor's clean."
  2170. fixer@faxcsl.dcrt.nih.gov    |                 - Sidney Harris
  2171.  
  2172. +++++++++++++++++++++++++++
  2173.  
  2174. >From christer@cs.umu.se (Christer Ericson)
  2175. Date: Tue, 10 May 1994 10:24:38 GMT
  2176. Organization: Dept. of Computing Science, Umea Univ., 901 87 Umea, Sweden
  2177.  
  2178. In <00148DC5.fc@bmug.org> Ron_Hunsinger@bmug.org (Ron Hunsinger) writes:
  2179. >
  2180. >parkb@bigbang.Stanford.EDU (Brian Park) writes:
  2181. >>[...suggests using Newton's method...]
  2182. >
  2183. >You can do square root much faster than this.
  2184.  
  2185. I beg to differ. In article <CpA23t.DwM@cs.umu.se> I posted an 68000-
  2186. based implementation of Newton's method (with quirks) which is something
  2187. like 20-30% faster than the equivalent hand-coded optimized assembly
  2188. version of the routine you posted in another article. It all depends on
  2189. how good your initial guess for Newton's method is.
  2190.  
  2191. So there! :-)
  2192.  
  2193.  
  2194. Christer Ericson --- Internet: christer@cs.umu.se --- tel: +46-90-166794
  2195. Department of Computer Science, University of Umea, S-90187 UMEA, SWEDEN
  2196.  
  2197. +++++++++++++++++++++++++++
  2198.  
  2199. >From afcjlloyd@aol.com (AFC JLloyd)
  2200. Date: 10 May 1994 18:01:03 -0400
  2201. Organization: America Online, Inc. (1-800-827-6364)
  2202.  
  2203. In article <CpL0x4.HKJ@cs.umu.se>, christer@cs.umu.se (Christer Ericson)
  2204. writes:
  2205.  
  2206. >In <00148DC5.fc@bmug.org> Ron_Hunsinger@bmug.org (Ron Hunsinger) writes:
  2207. >>
  2208. >>parkb@bigbang.Stanford.EDU (Brian Park) writes:
  2209. >>>[...suggests using Newton's method...]
  2210. >>
  2211. >>You can do square root much faster than this.
  2212. >
  2213. >I beg to differ. In article <CpA23t.DwM@cs.umu.se> I posted an 68000-
  2214. >based implementation of Newton's method (with quirks) which is something
  2215. >like 20-30% faster than the equivalent hand-coded optimized assembly
  2216. >version of the routine you posted in another article. It all depends on
  2217. >how good your initial guess for Newton's method is.
  2218.  
  2219. I agree with Christer.  Until this thread I had been using Newton's method
  2220. with 5 iterations for obtaining the square root of unsigned longs, where
  2221. the initial estimate came from finding the most signficant bit, using
  2222. that to estimate Log2(n), and using that to estimate sqrt(n).
  2223.  
  2224. When I saw this thread I tried the code attributed to Dr. John Bruner
  2225. (similar to Ron's code) and saw a 40% speedup over my Newton's method
  2226. code.  Convinced that this was a precious find,  I then tried to apply 
  2227. the same technique to taking the square root of Fixed point values and 
  2228. discovered that it couldn't beat my Newton's method code.  The reason 
  2229. was primarily that 24 (instead of 16) iterations are required for 
  2230. fixed point square root (the Fract case would require 31 iterations).
  2231.  
  2232. This caused me to do more thinking about Newton's method.  
  2233. The great thing about Newton's method is that it _doubles_ the 
  2234. precision with each iteration.  Of course, double of nothing
  2235. is nothing, so Newton's method is worthless if you give it a poor
  2236. estimate, but given a good estimate Newton's method is fantastic.
  2237.  
  2238. So, I decided to use a table lookup to provide the initial estimate for
  2239. Newton's method.  I found that I could reduce the number of iterations
  2240. down from five to _one_ for the integer case, and just _two_ iterations
  2241. for both the Fixed and Fract cases.  The resulting code is significantly
  2242. faster than any of my previous attempts.
  2243.  
  2244. Jim Lloyd
  2245. afcjlloyd@aol.com
  2246.  
  2247.  
  2248. +++++++++++++++++++++++++++
  2249.  
  2250. >From Ron_Hunsinger@bmug.org (Ron Hunsinger)
  2251. Date: Sat, 14 May 94 03:01:56 PST
  2252. Organization: Berkeley Macintosh Users Group
  2253.  
  2254. christer@cs.umu.se (Christer Ericson) writes:
  2255.  
  2256. >In <00148DC5.fc@bmug.org> Ron_Hunsinger@bmug.org (Ron Hunsinger) writes:
  2257. >>
  2258. >>parkb@bigbang.Stanford.EDU (Brian Park) writes:
  2259. >>>[...suggests using Newton's method...]
  2260. >>
  2261. >>You can do square root much faster than this.
  2262. >
  2263. >I beg to differ. In article <CpA23t.DwM@cs.umu.se> I posted an 68000-
  2264. >based implementation of Newton's method (with quirks) which is something
  2265. >like 20-30% faster than the equivalent hand-coded optimized assembly
  2266. >version of the routine you posted in another article. It all depends on
  2267. >how good your initial guess for Newton's method is.
  2268.  
  2269. You've got me mixed up with somebody else.  I did say you can do square
  2270. root much faster, and explained how, but I didn't post any assembly
  2271. version.  I posted the C version (which therefore has the advantage
  2272. that it can be compiled native for PowerPC, or ported easily to another
  2273. machine that doesn't even have to be binary, although of course it is
  2274. unlikely that shifting will be fast on a non-binary machine).
  2275.  
  2276. I saw two assembly versions.  One, which was quite long, very tightly
  2277. optimized, and attributed to Motorola, was indeed faster than my short 
  2278. simple C version, but not by all that much.  Also, it always truncated,
  2279. where mine would produce the correctly rounded result (or the truncated
  2280. result by commenting out one line if that's really what you wanted).
  2281.  
  2282. The other, very short assembler version was hopelessly flawed.  It
  2283. computed an initial guess that could be off by a factor of two, and
  2284. then did *ONE* iteration of Newton's method, and stopped there, producing
  2285. a value that was not even close (in absolute terms), even when it did
  2286. not lose all significance due to overflow.  If asked to take the square 
  2287. root of zero, it would divide by zero.  It probably was fast (when it
  2288. didn't crash), but who cares how quickly you get the wrong answer?
  2289.  
  2290. Which version was yours?
  2291.  
  2292. I'll be charitable and assume it was the Motorola version.  I no longer
  2293. have the original message, but I seem to recall the max running time
  2294. was something like 1262 cycles on a 68000, and (quite a bit) faster
  2295. on small values.  I modified my C version to special-case small values
  2296. too, and unwind the iterations of the main loop up to the iteration that
  2297. finds the high bit of the root.  The main benefit of special-casing small 
  2298. values is so I don't have to worry about that boundary in the remaining 
  2299. code -- I am then guaranteed that the (unrounded) root is at least two 
  2300. bits long.  And although I am not displeased by the improved efficiency, 
  2301. my main reason for unwinding the first iterations was to remove the 
  2302. restriction in the prior version that it would only work on machines in 
  2303. which the number of bits in an unsigned long was even.  This code will 
  2304. now work even on machines with odd integer sizes.  (Yes, Virginia, such 
  2305. machines do exist!  An example is the Unisys A-series computers, in which 
  2306. ALL arithmetic is done in floating point, and integers are just the special 
  2307. case where the exponent is zero and the integer value is stored in the 
  2308. 39-bit mantissa of a 48-bit word.)  
  2309.  
  2310. My improved C version appears at the end of this message.
  2311.  
  2312. I compiled it with MPW C with no special optimizations, tested it
  2313. thoroughly, and then disassembled the code and calculated the running
  2314. time on a 68000.  (On later machines, the presence of the cache makes
  2315. accurate timings much more difficult to do by hand.)  I did not make
  2316. any attempt to "improve" the C-generated code, although there are some 
  2317. easy and obvious optimizations available.  The running time for my
  2318. version (the one that correctly rounds), counting the RTS and the
  2319. (quite unnecessary) LINK/MOVEM.L/.../MOVE.L <rslt>,D0/MOVEM.L/UNLK is:
  2320.  
  2321.    If N <= 12 then 204+4N, else 620+46u+32z+6r, where
  2322.         N = input argument
  2323.         u = Number of one-bits in the unrounded root
  2324.         z = Number of non-leading zero-bits in the unrounded root
  2325.         r = 1 if rounding increases the root, else 0
  2326.  
  2327.    The actual running time for various values of N is:
  2328.  
  2329.                  N   Time  Comments
  2330.          ---------  -----  -------------------------
  2331.                  0    204  Best time
  2332.                 13    718  Best time not using lookup table
  2333.                625    822  This is a cut-point for the Motorola code
  2334.           0..65535    935  Average* time over inputs that fit in 16 bits
  2335.              65535    994  Worst time if N fits in 16 bits
  2336.      0..0xFFFFFFFF   1247  Average* time over all 32-bit inputs
  2337.         0xFFFFFFFF   1362  Worst case
  2338.        *average times computed assuming uniform distrubution of outputs
  2339.  
  2340. If my memory serves me right, this is only about 8% slower than the
  2341. hand-crafted Motorola code, which I think is a cheap price to pay for
  2342. the portability.  Especially considering that most of that difference 
  2343. is due to the fact that they split the general loop into a main loop 
  2344. that could get away with word-size operations for some variables, and 
  2345. a few unwound iterations that had to use long-sized operands.  Notice
  2346. that this is counterproductive on 68020 and up, where long operations 
  2347. are just as fast as word operations when the operands are in registers,
  2348. and the only effect of unwinding the last two iterations is to 
  2349. guarantee that they won't be in the cache.  
  2350.  
  2351. The compiled 68K code fits in 104 bytes (decimal). (96 bytes without
  2352. the debugger symbol. This really was a vanilla compile.)  How big was 
  2353. your code?  How big is the code cache on your machine?  How much of
  2354. your caller's code do you push out of the cache?
  2355.  
  2356.  
  2357. >So there! :-)
  2358.  
  2359. Same to you!!  :-)
  2360.  
  2361.  
  2362. #define lsqrt_max4pow (1UL << 30)
  2363. // lsqrt_max4pow is the (machine-specific) largest power of 4 that can
  2364. // be represented in an unsigned long.
  2365.  
  2366. unsigned long lsqrt (unsigned long n) {
  2367.     // Compute the integer square root of the integer argument n
  2368.     // Method is to divide n by x computing the quotient x and remainder r
  2369.     // Notice that the divisor x is changing as the quotient x changes
  2370.  
  2371.     // Instead of shifting the dividend/remainder left, we shift the
  2372.     // quotient/divisor right.  The binary point starts at the extreme
  2373.     // left, and shifts two bits at a time to the extreme right.
  2374.  
  2375.     // The residue contains n-x^2.  (Within these comments, the ^ operator
  2376.     // signifies exponentiation rather than exclusive or.  Also, the /
  2377.     // operator returns fractions, rather than truncating, so 1/4 means
  2378.     // one fourth, not zero.)
  2379.  
  2380.     // Since (x + 1/2)^2 == x^2 + x + 1/4,
  2381.     //   n - (x + 1/2)^2 == (n - x^2) - (x + 1/4)
  2382.     // Thus, we can increase x by 1/2 if we decrease (n-x^2) by (x+1/4)
  2383.  
  2384.     unsigned long residue;      // n - x^2
  2385.     unsigned long root;         // x + 1/4
  2386.     unsigned long half;         // 1/2
  2387.  
  2388.     residue = n;                // n - (x = 0)^2, with suitable alignment
  2389.     
  2390.     // if the correct answer fits in two bits, pull it out of a magic hat
  2391. #ifndef lsqrt_truncate
  2392.     if (residue <= 12)
  2393.         return (0x03FFEA94 >> (residue *= 2)) & 3;
  2394. #else
  2395.     if (residue <= 15)
  2396.         return (0xFFFEAA54 >> (residue *= 2)) & 3;
  2397. #endif
  2398.     root = lsqrt_max4pow;       // x + 1/4, shifted all the way left
  2399. //  half = root + root;         // 1/2, shifted likewise
  2400.     
  2401.     // Unwind iterations corresponding to leading zero bits 
  2402.     while (root > residue) root >>= 2;
  2403.     
  2404.     // Unwind the iteration corresponding to the first one bit
  2405.     // Operations have been rearranged and combined for efficiency
  2406.     // Initialization of half is folded into this iteration
  2407.     residue -= root;            // Decrease (n-x^2) by (0+1/4)
  2408.     half = root >> 2;           // 1/4, with binary point shifted right 2
  2409.     root += half;               // x=1.  (root is now (x=1)+1/4.)
  2410.     half += half;               // 1/2, properly aligned
  2411.  
  2412.     // Normal loop (there is at least one iteration remaining)
  2413.     do {
  2414.         if (root <= residue) {  // Whenever we can,
  2415.             residue -= root;        // decrease (n-x^2) by (x+1/4)
  2416.             root += half; }         // increase x by 1/2
  2417.         half >>= 2;             // Shift binary point 2 places right
  2418.         root -= half;           // x{+1/2}+1/4 - 1/8 == x{+1/2}+1/8
  2419.         root >>= 1;             // 2x{+1}+1/4, shifted right 2 places
  2420.         } while (half);         // When 1/2 == 0, bin. point is at far right
  2421.  
  2422. #ifndef lsqrt_truncate
  2423.     if (root < residue) ++root;  // round up if (x+1/2)^2 < n
  2424. #endif
  2425.     
  2426.     return root;        // Guaranteed to be correctly rounded (or truncated)
  2427.     }
  2428.  
  2429. -Ron Hunsinger
  2430.  
  2431. +++++++++++++++++++++++++++
  2432.  
  2433. >From christer@cs.umu.se (Christer Ericson)
  2434. Date: Mon, 16 May 1994 08:44:47 GMT
  2435. Organization: Dept. of Computing Science, Umea Univ., 901 87 Umea, Sweden
  2436.  
  2437. In <0014E819.fc@bmug.org> Ron_Hunsinger@bmug.org (Ron Hunsinger) writes:
  2438. >
  2439. >christer@cs.umu.se (Christer Ericson) writes:
  2440. >>[...]
  2441. >>I beg to differ. In article <CpA23t.DwM@cs.umu.se> I posted an 68000-
  2442. >>based implementation of Newton's method (with quirks) which is something
  2443. >>like 20-30% faster than the equivalent hand-coded optimized assembly
  2444. >>version of the routine you posted in another article. It all depends on
  2445. >>how good your initial guess for Newton's method is.
  2446. >
  2447. >You've got me mixed up with somebody else.  I did say you can do square
  2448. >root much faster, and explained how, but I didn't post any assembly
  2449. >version.  I posted the C version (which therefore has the advantage
  2450. >that it can be compiled native for PowerPC, or ported easily to another
  2451. >machine that doesn't even have to be binary, although of course it is
  2452. >unlikely that shifting will be fast on a non-binary machine).
  2453.  
  2454. Gosh! What if you read what I wrote above. I didn't claim your code was
  2455. written in assembly. I refer rather clearly to highly optimized assembly
  2456. code _equivalent_ to the C code you posted.
  2457.  
  2458.  
  2459. >I saw two assembly versions.  One, which was quite long, very tightly
  2460. >optimized, and attributed to Motorola, was indeed faster than my short 
  2461. >simple C version, but not by all that much.  Also, it always truncated,
  2462. >where mine would produce the correctly rounded result (or the truncated
  2463. >result by commenting out one line if that's really what you wanted).
  2464. >
  2465. >The other, very short assembler version was hopelessly flawed.  It
  2466. >computed an initial guess that could be off by a factor of two, and
  2467. >then did *ONE* iteration of Newton's method, and stopped there, producing
  2468. >a value that was not even close (in absolute terms), even when it did
  2469. >not lose all significance due to overflow.  If asked to take the square 
  2470. >root of zero, it would divide by zero.  It probably was fast (when it
  2471. >didn't crash), but who cares how quickly you get the wrong answer?
  2472. >
  2473. >Which version was yours?
  2474.  
  2475. Neither of these. Instead of arguing about some program you thought I
  2476. wrote, wouldn't it have been better (as well as making you look better)
  2477. if you had looked my article up, or in the case it had expired at your
  2478. site, requested a copy from me before making yourself silly in public?
  2479.  
  2480. Instead of commenting on your rather irrelevant comments on some code
  2481. that wasn't mine, I've appended below a copy of my code and if you
  2482. care to compare it to your code, I'll take the time to respond to
  2483. any comments you might have (size, speed, what have you). Fair?
  2484.  
  2485. Finally, the point I wanted to make was that an optimized version of
  2486. Newton's method very well beats an optimized version of the type of
  2487. algorithm your program is a version of. I'm not interested in any
  2488. "...b-b-b-but C is more portable..." arguments.
  2489.  
  2490.  
  2491. - - cut here ---
  2492. unsigned short ce_quick_sqrt(n)
  2493. register unsigned long n;
  2494. {
  2495.     asm {
  2496. ;-------------------------
  2497. ;
  2498. ; Routine       : ISQRT; integer square root
  2499. ; I/O parameters: d0.w = sqrt(d0.l)
  2500. ; Registers used: d0-d2/a0
  2501. ;
  2502. ; This is a highly optimized integer square root routine, based
  2503. ; on the iterative Newton/Babylonian method
  2504. ;
  2505. ;    r(n + 1) = (r(n) + A / R(n)) / 2
  2506. ;
  2507. ; Verified over the full interval [0x0L,0xFFFFFFFFL]
  2508. ;
  2509. ; Some minor compromises have been made to make it perform well
  2510. ; on the 68000 as well as 68020/030/040. This routine outperforms
  2511. ; the best of all other algorithms I've seen (except for a table
  2512. ; lookup).
  2513. ;
  2514. ; Copyright (c) Christer Ericson, 1993. All rights reserved.
  2515. ;
  2516. ; Christer Ericson, Dept. of Computer Science, University of Umea,
  2517. ; S-90187 UMEA, SWEDEN. Internet: christer@cs.umu.se
  2518. ;
  2519.  
  2520. ;-------------------------
  2521. ;
  2522. ; Macintosh preamble since THINK C passes first register param
  2523. ; in d7. Remove this section on any other machine
  2524. ;
  2525.     move.l    d7,d0
  2526. ;-------------------------
  2527. ;
  2528. ; Actual integer square root routine starts here
  2529. ;
  2530.     move.l    d0,a0        ; save original input value for the iteration
  2531.     beq.s    @exit        ; unfortunately we must special case zero
  2532.     moveq    #2,d1        ; init square root guess
  2533. ;-------------------------
  2534. ;
  2535. ; Speed up the process of finding a power of two approximation
  2536. ; to the actual square root by shifting an appropriate amount
  2537. ; when the input value is large enough
  2538. ;
  2539. ; If input values are word only, this section can be removed
  2540. ;
  2541.     move.l    d0,d2
  2542.     swap    d2        ; do [and.l 0xFFFF0000,d2] this way to...
  2543.     tst.w    d2        ; go faster on 68000 and to avoid having to...
  2544.     beq.s    @skip8        ; reload d2 for the next test below
  2545.     move.w    #0x200,d1    ; faster than lsl.w #8,d1 (68000)
  2546.     lsr.l    #8,d0
  2547. @skip8    and.w    #0xFE00,d2    ; this value and shift by 5 are magic
  2548.     beq.s    @skip4
  2549.     lsl.w    #5,d1
  2550.     lsr.l    #5,d0
  2551. @skip4
  2552.  
  2553. ;-------------------------
  2554. ;
  2555. ; This finds the power of two approximation to the actual square root
  2556. ; by doing the integer equivalent to sqrt(x) = 2 ^ (log2(x) / 2). This
  2557. ; is done by shifting the input value down while shifting the root
  2558. ; approximation value up until they meet in the middle. Better precision
  2559. ; (in the step described below) is gained by starting the approximation
  2560. ; at 2 instead of 1 (this means that the approximation will be a power
  2561. ; of two too large so remember to shift it down).
  2562. ;
  2563. ; Finally (and here's the clever thing) since, by previously shifting the
  2564. ; input value down, it has actually been divided by the root approximation
  2565. ; value already so the first iteration is "for free". Not bad, eh?
  2566. ;
  2567. @loop    add.l    d1,d1
  2568.     lsr.l    #1,d0
  2569.     cmp.l    d0,d1
  2570.     bcs.s    @loop
  2571. @skip    lsr.l    #1,d1        ; adjust the approximation
  2572.     add.l    d0,d1        ; here we just add and shift to...
  2573.     lsr.l    #1,d1        ; get the first iteration "for free"!
  2574. ;-------------------------
  2575. ;
  2576. ; The iterative root value is guaranteed to be larger than (or equal to)
  2577. ; the actual square root, except for the initial guess. But since the first
  2578. ; iteration was done above, the loop test can be simplified below
  2579. ; (Oh, without the bvs.s the routine will fail on most large numbers, like
  2580. ; for instance, 0xFFFF0000. Could there be a better way of handling these,
  2581. ; so the bvs.s can be removed? Nah...)
  2582. ;
  2583. @loop2    move.l    a0,d2        ; get original input value
  2584.     move.w    d1,d0        ; save current guess
  2585.     divu.w    d1,d2        ; do the Newton method thing
  2586.     bvs.s    @exit        ; if div overflows, exit with current guess
  2587.     add.w    d2,d1
  2588.     roxr.w    #1,d1        ; roxr ensures shifting back carry overflow
  2589.     cmp.w    d0,d1
  2590.     bcs.s    @loop2        ; exit with result in d0.w
  2591. @exit
  2592.     }
  2593. }
  2594.  
  2595. Christer Ericson --- Internet: christer@cs.umu.se --- tel: +46-90-166794
  2596. Department of Computer Science, University of Umea, S-90187 UMEA, SWEDEN
  2597.  
  2598. +++++++++++++++++++++++++++
  2599.  
  2600. >From Ron_Hunsinger@bmug.org (Ron Hunsinger)
  2601. Date: Tue, 24 May 94 23:23:06 PST
  2602. Organization: Berkeley Macintosh Users Group
  2603.  
  2604. christer@cs.umu.se (Christer Ericson) writes:
  2605.  
  2606. >In <0014E819.fc@bmug.org> Ron_Hunsinger@bmug.org (Ron Hunsinger) writes:
  2607. >>
  2608. >>christer@cs.umu.se (Christer Ericson) writes:
  2609. >>>[...]
  2610. >>>I beg to differ. In article <CpA23t.DwM@cs.umu.se> I posted an 68000-
  2611. >>>based implementation of Newton's method (with quirks) which is something
  2612. >>>like 20-30% faster than the equivalent hand-coded optimized assembly
  2613. >>>version of the routine you posted in another article. It all depends on
  2614. >>>how good your initial guess for Newton's method is.
  2615. >>
  2616. >>You've got me mixed up with somebody else.  I did say you can do square
  2617. >>root much faster, and explained how, but I didn't post any assembly
  2618. >>version.  I posted the C version (which therefore has the advantage
  2619. >>that it can be compiled native for PowerPC, or ported easily to another
  2620. >>machine that doesn't even have to be binary, although of course it is
  2621. >>unlikely that shifting will be fast on a non-binary machine).
  2622. >
  2623. >Gosh! What if you read what I wrote above. I didn't claim your code was
  2624. >written in assembly. I refer rather clearly to highly optimized assembly
  2625. >code _equivalent_ to the C code you posted.
  2626.  
  2627. I did read what you wrote.  You have to admit that it isn't all that
  2628. clear.  One could, and I did, read it that you thought I had posted an
  2629. "equivalent hand-coded optimized assembly".
  2630.  
  2631. But as long as we're on the subject of carefully reading each other's
  2632. notes, lets look again at what I said.  I said that Newton/Raphson was
  2633. not the fastest ALGORITHM for taking square roots, because it uses
  2634. several division steps, and there is another algorithm (which I described)
  2635. which is as fast as a single division.  I also made it clear that in
  2636. making that comparison, I was comparing only similar implementations
  2637. of the two operations: my sqare root method implemented entirely in
  2638. software is as fast and about the same size as division implemented
  2639. entirely in software; my square root method implemented entirely in
  2640. hardware is as fast and uses about the same number of logic gates as
  2641. division implemented entirely in hardware.
  2642.  
  2643. Comparing my wholly-software IMPLEMENTATION to your implementation using
  2644. hardware divide is unfair and irrelevant.  I stand by my claim.  Square
  2645. root is no harder or slower than division.  And there is an algorithm
  2646. for square root that will beat Newton/Raphson hands down whenever both
  2647. algorithms are given similar implementations.
  2648.  
  2649. To back up my claim, consider that ANY software-only implementation of 
  2650. Newton/Raphson would have to, as a minimum, test for a zero input (to 
  2651. avoid dividing by zero), and do at least one division.  That is, it would 
  2652. have to be at least as complex as the following routine to compute a 
  2653. sort-of reciprocal:
  2654.  
  2655.     unsigned long lrecip (unsigned long n) {
  2656.         return (n == 0) ? 0 : 0xFFFFFFFF / n;
  2657.         }
  2658.  
  2659. On a 68000, the division has to be done in software, because the 68000
  2660. does not have a DIVU.L instruction.  Examining the code generated by
  2661. this routine shows that its worst-case running time on a 68000 is 1312 
  2662. clocks.  My square-root routine takes at most 1362 clocks.  Close enough?
  2663.  
  2664.  
  2665. >Finally, the point I wanted to make was that an optimized version of
  2666. >Newton's method very well beats an optimized version of the type of
  2667. >algorithm your program is a version of. I'm not interested in any
  2668. >"...b-b-b-but C is more portable..." arguments.
  2669.  
  2670. But I DO care that C is more portable, and it is definitely relevant to
  2671. the comparison.  Our versions were not optimized equivalently, because
  2672. you are focusing only on optimization to a particular piece of silicon
  2673. that happens to implement division, but not square root, in hardware.
  2674. Take our implementations unchanged, and run them on a PowerPC, and mine
  2675. will leave yours in the dust.  ("Unchanged" means I get to compile mine
  2676. native - that's what I bought when I paid the price of being portable.
  2677. "Unchanged" means you have to have yours emulated - that's what you
  2678. bought when you decided to write processor-dependent code.)  Or take
  2679. our implementations unchanged and run them on an Intel processor.  Watch
  2680. mine still run at acceptable speed.  Watch yours not run at all.
  2681.  
  2682. I also care that mine meets the design specs.  The original requestor
  2683. said he wanted to compute square root "rounded to the nearest integer".
  2684. My method rounds, and rounds correctly in every case.  Yours, and all
  2685. the other methods I've seen, truncate.  I can truncate too, if that's
  2686. what you want, but fixing yours to round takes a little work.  Essentially,
  2687. rounding involves comparing the unrounded root with the remainder from
  2688. the last division.  If you implement Newton/Raphson in C or Pascal, that
  2689. remainder is not available to you, and you have to do at least another
  2690. multiply and subtract to get it.  If done in 68K Assembler, the remainder
  2691. is available, so rounding won't slow you down much, but it will complicate
  2692. your logic some, and of course there's that portability issue you don't
  2693. want to talk about.  Either way, remember that rounding may produce a 
  2694. result of 65536, so the routine has to return an unsigned long, just 
  2695. like the requestor asked for, instead of an unsigned short.
  2696.  
  2697. >I've appended below a copy of my code and if you
  2698. >care to compare it to your code, I'll take the time to respond to
  2699. >any comments you might have (size, speed, what have you). Fair?
  2700.  
  2701. Well OK, as long as you keep in mind we're comparing apples to
  2702. oranges.
  2703.  
  2704. Before looking at speed, there is the more important issue of 
  2705. correctness.  As nearly as I can tell, you always return the correct 
  2706. value (except for not rounding).  I won't quite go so far as to say the 
  2707. code is all correct, because you make some early mistakes that get 
  2708. compensated for later:
  2709.  
  2710.   o You test for a zero input by doing a BEQ.S right after moving the
  2711.     input to register A0 for safekeeping.  Are you aware that moving to
  2712.     an A register does not affect the condition codes?  Fortunately,
  2713.     the condition codes are still set correctly from the prior move
  2714.     of the same data from D7 to D0.  However, you have a comment that
  2715.     says that move can be eliminated.  If someone does, they might be 
  2716.     in trouble.
  2717.  
  2718.   o Your logic to do large initial shifts is faulty.  On some inputs (like
  2719.     0x02000000) you overshift.  On other inputs (in the range 512..65535) 
  2720.     I think you are not shifting as far as you think you are shifting.  
  2721.     (The logic around label @skip8 is muddled.)  Fortunately, the Newton 
  2722.     method is robust enough to compensate for a bad initial guess, and
  2723.     you still arrive at the correct answer, although not as efficiently
  2724.     as you could have.
  2725.  
  2726. Maybe you don't care about either of these points - after all, you already 
  2727. said you didn't care about portability - but has no one ever pointed out
  2728. to you that is much easier to write provably correct code in a high level
  2729. language?  Does the fact that your code does not work the way you think it 
  2730. does suggest anything?
  2731.  
  2732. It's hard to estimate your average running time, because there are
  2733. so many paths through the optimization and it's difficult to assign
  2734. proper weights to each path, so I'll settle for comparing worst cases.
  2735.  
  2736.   o Your worst case is with the input 0x02000000, for which you have to
  2737.     do 4 divisions.  You take a total of 994 clocks on a 68000, or
  2738.     459 clocks on a 68020.
  2739.  
  2740.   o My worst case is with the input 0xFFFFFFFF.  I take 1362 clocks on
  2741.     a 68000, 609 on a 68020.
  2742.  
  2743. 1362 / 994 = 1.37.  You are 37% faster than I am on a 68000.
  2744. 609 / 459 = 1.33.  You are 33% faster than I am on a 68020.
  2745.  
  2746. Truth be told, I'm not unhappy that my portable software solution fares
  2747. so well against your non-portable hardware solution, even on the hardware
  2748. of your choice.  Your speed advantage stems from the fact that you are
  2749. coding in Assembler, not from any advantage of the algorithm.  If you 
  2750. implemented your algorithm in C, then either your code would be calling a
  2751. division subroutine (and your performance would go to hell), or you
  2752. could specifically tell the compiler to generate 68020 code to get
  2753. inline divide instructions.  But then, besides no longer running on a 
  2754. 68000, you would still come out behind because the compiler would be
  2755. compelled to generate a DIVU.L instruction instead of your DIVU.W, and 
  2756. that difference alone is enough to dissipate all your advantage.  Add 
  2757. the extra multiply you need to do correct rounding and you're behind.
  2758.  
  2759. -Ron Hunsinger
  2760.  
  2761. +++++++++++++++++++++++++++
  2762.  
  2763. >From christer@cs.umu.se (Christer Ericson)
  2764. Date: Thu, 2 Jun 1994 08:17:18 GMT
  2765. Organization: Dept. of Computing Science, Umea Univ., 901 87 Umea, Sweden
  2766.  
  2767. In <00155867.fc@bmug.org> Ron_Hunsinger@bmug.org (Ron Hunsinger) writes:
  2768. >[...]                                  I also made it clear that in
  2769. >making that comparison, I was comparing only similar implementations
  2770. >of the two operations: my sqare root method implemented entirely in
  2771. >software is as fast and about the same size as division implemented
  2772. >entirely in software; my square root method implemented entirely in
  2773. >hardware is as fast and uses about the same number of logic gates as
  2774. >division implemented entirely in hardware.
  2775.  
  2776. OK, I can agree with that. But apart from that... well, see below.
  2777.  
  2778.  
  2779. >Comparing my wholly-software IMPLEMENTATION to your implementation using
  2780. >hardware divide is unfair and irrelevant.  I stand by my claim.  Square
  2781. >root is no harder or slower than division.  And there is an algorithm
  2782. >for square root that will beat Newton/Raphson hands down whenever both
  2783. >algorithms are given similar implementations.
  2784.  
  2785. It's neither unfair nor irrelevant. You're living in a dream world.
  2786. In the real world (where the rest of us live) there's no such thing
  2787. as "similar implementations". The better (which equals to faster in
  2788. this case) implementation wins, regardless of whether it uses all
  2789. available machine instructions or not.
  2790.  
  2791. In the real world do you always cry, "Not fair! Not fair! You used
  2792. hardware division and I didn't <stomp of feet>."? Hey, good luck to you!
  2793.  
  2794.  
  2795. >But I DO care that C is more portable, and it is definitely relevant to
  2796. >the comparison.  Our versions were not optimized equivalently, because
  2797. >you are focusing only on optimization to a particular piece of silicon
  2798. >that happens to implement division, but not square root, in hardware.
  2799. >Take our implementations unchanged, and run them on a PowerPC, and mine
  2800. >will leave yours in the dust.  ("Unchanged" means I get to compile mine
  2801. >native - that's what I bought when I paid the price of being portable.
  2802. >"Unchanged" means you have to have yours emulated - that's what you
  2803. >bought when you decided to write processor-dependent code.)  Or take
  2804. >our implementations unchanged and run them on an Intel processor.  Watch
  2805. >mine still run at acceptable speed.  Watch yours not run at all.
  2806.  
  2807. You're being silly! I use my code as posted on a 68K machine, I use another
  2808. (general) piece of code on another machine. Ever heard the word #ifdef?
  2809.  
  2810.  
  2811. >I also care that mine meets the design specs.  The original requestor
  2812. >said he wanted to compute square root "rounded to the nearest integer".
  2813. >My method rounds, and rounds correctly in every case.  Yours, and all
  2814. >the other methods I've seen, truncate.  I can truncate too, if that's
  2815. >what you want, but fixing yours to round takes a little work.  Essentially,
  2816. >rounding involves comparing the unrounded root with the remainder from
  2817. >the last division.  If you implement Newton/Raphson in C or Pascal, that
  2818. >remainder is not available to you, and you have to do at least another
  2819. >multiply and subtract to get it.  If done in 68K Assembler, the remainder
  2820. >is available, so rounding won't slow you down much, but it will complicate
  2821. >your logic some, and of course there's that portability issue you don't
  2822. >want to talk about.  Either way, remember that rounding may produce a 
  2823. >result of 65536, so the routine has to return an unsigned long, just 
  2824. >like the requestor asked for, instead of an unsigned short.
  2825.  
  2826. I didn't post my article as a reply to the original post, but as a proof
  2827. that a carefully coded N/B-approach very well outperforms (in terms of
  2828. execution time) the algebraic algorithm your code is a version of.
  2829.  
  2830.  
  2831. >>[I wrote:]
  2832. >>I've appended below a copy of my code and if you
  2833. >>care to compare it to your code, I'll take the time to respond to
  2834. >>any comments you might have (size, speed, what have you). Fair?
  2835. >
  2836. >Well OK, as long as you keep in mind we're comparing apples to
  2837. >oranges.
  2838.  
  2839. I think it's interesting to note that when you compared your code to
  2840. Jim Cathey's code (which you erroneously thought was mine), then you
  2841. thought size was important. Was that only because your code was smaller
  2842. than Cathey's? Now that my code is smaller than yours, it seems that
  2843. you don't think size is important no longer. Nor did you bother to
  2844. compare average times.
  2845.  
  2846. And this from someone who cries "fair" all the time...
  2847.  
  2848.  
  2849. >Before looking at speed, there is the more important issue of 
  2850. >correctness.  As nearly as I can tell, you always return the correct 
  2851. >value (except for not rounding).  I won't quite go so far as to say the 
  2852. >code is all correct, because you make some early mistakes that get 
  2853. >compensated for later:
  2854. >
  2855. >  o You test for a zero input by doing a BEQ.S right after moving the
  2856. >    input to register A0 for safekeeping.  Are you aware that moving to
  2857. >    an A register does not affect the condition codes?  Fortunately,
  2858. >    the condition codes are still set correctly from the prior move
  2859. >    of the same data from D7 to D0.  However, you have a comment that
  2860. >    says that move can be eliminated.  If someone does, they might be 
  2861. >    in trouble.
  2862.  
  2863. Yes this is true. That comment is really a mistake. I added it in haste
  2864. when posting the code to comp.sys.m68k some while ago, when there were
  2865. a discussion of fast implementations of integer square roots. The comment
  2866. is faulty. The code is, and was, correct, however.
  2867.  
  2868.  
  2869. >  o Your logic to do large initial shifts is faulty.  On some inputs (like
  2870. >    0x02000000) you overshift.  On other inputs (in the range 512..65535) 
  2871. >    I think you are not shifting as far as you think you are shifting.  
  2872. >    (The logic around label @skip8 is muddled.)  Fortunately, the Newton 
  2873. >    method is robust enough to compensate for a bad initial guess, and
  2874. >    you still arrive at the correct answer, although not as efficiently
  2875. >    as you could have.
  2876.  
  2877. Harsh words from someone who doesn't bother to attribute code to the
  2878. correct person. There is nothing wrong with the section of code you're
  2879. refering to. That code is there to reduce the number of iterations in
  2880. the section just below, and to _reduce_it_as_much_as_possible_on_average_
  2881. _without_over-complicating_the_code_.
  2882.  
  2883. Now, say again, is it correct or is it faulty? If you consider it to
  2884. be faulty, I'd very much like to see you post what you consider to be
  2885. a correct version!
  2886.  
  2887.  
  2888. >Does the fact that your code does not work the way you think it 
  2889. >does suggest anything?
  2890.  
  2891. While we're being sarcastic, I'd like to ask you if the fact that you
  2892. find errors that aren't there suggest anything to you?
  2893.  
  2894.  
  2895. >It's hard to estimate your average running time, because there are
  2896. >so many paths through the optimization and it's difficult to assign
  2897. >proper weights to each path, so I'll settle for comparing worst cases.
  2898. >
  2899. >  o Your worst case is with the input 0x02000000, for which you have to
  2900. >    do 4 divisions.  You take a total of 994 clocks on a 68000, or
  2901. >    459 clocks on a 68020.
  2902. >
  2903. >  o My worst case is with the input 0xFFFFFFFF.  I take 1362 clocks on
  2904. >    a 68000, 609 on a 68020.
  2905. >
  2906. >1362 / 994 = 1.37.  You are 37% faster than I am on a 68000.
  2907. >609 / 459 = 1.33.  You are 33% faster than I am on a 68020.
  2908.  
  2909. Well, since you didn't bother running the code, I did. On an IIcx I got
  2910. the following results (all numbers in ticks):
  2911.  
  2912. R = Ron's code, as posted
  2913. A = Optimized assembly code equivalent to Ron's code
  2914. C = My code, as posted
  2915.  
  2916.     [0..65536)    [0..500000)    500000 "random" numbers
  2917. R    142        1088        1135
  2918. A    118        906        944
  2919. C    95        626        473
  2920.  
  2921. 142 / 95 = 1.49
  2922. 1088 / 626 = 1.74
  2923. 1135 / 473 = 2.4
  2924.  
  2925. These figures should be considerably larger on a 68000, if we can believe
  2926. your figures. (Note that you could squeeze an extra 20% out of your code,
  2927. which for what is essentially a library routine is quite large. I would use
  2928. my code though.)
  2929.  
  2930.  
  2931. >Truth be told, I'm not unhappy that my portable software solution fares
  2932. >so well against your non-portable hardware solution, even on the hardware
  2933. >of your choice.
  2934.  
  2935. You were saying?
  2936.  
  2937.  
  2938. Christer Ericson --- Internet: christer@cs.umu.se --- tel: +46-90-166794
  2939. Department of Computer Science, University of Umea, S-90187 UMEA, SWEDEN
  2940.  
  2941. ---------------------------
  2942.  
  2943. >From baer@qiclab.scn.rain.com (Ken Baer)
  2944. Subject: How to save alpha in PICT files?
  2945. Date: Sat, 28 May 1994 00:24:17 GMT
  2946. Organization: SCN Research/Qic Laboratories of Tigard, Oregon.
  2947.  
  2948. I need to save 32-bit images as PICT files that include the upper 8 bits
  2949. of data (the alpha buffer).  My code currently saves as 32-bit PICT files,
  2950. but the upper 8-bit of data are missing!  I am using the methods described
  2951. in Inside Mac and developer notes.  The sequence I use now is as follows:
  2952.  - allocate and write 32-bit data to an offscreen GWorld
  2953.  - OpenPicture()
  2954.  - CopyBits(offgworld, offgworld) (copy the pixmap to itself)
  2955.  - ClosePicture()
  2956.  
  2957. Is there an extra writing step to jam in the alpha buffer?  Is there any
  2958. sample code (in C) with a more modern method?  The sample code I'm working
  2959. from is pretty dated.
  2960.  
  2961. Thanks in advance.
  2962.  
  2963.     -Ken Baer.
  2964.     baer@qiclab.scn.rain.com
  2965. -- 
  2966.  \_       -Ken Baer.  Programmer/Animator, Hash Inc.
  2967. <[_]   Usenet: baer@qiclab.scn.rain.com/AppleLink:KENBAER/Office: (206)750-0042
  2968.  =# \, Animation Master: Finally, 3D animation software an artist can afford!
  2969.  
  2970. +++++++++++++++++++++++++++
  2971.  
  2972. >From zapper2@netcom.com (Chris Athanas)
  2973. Date: Sun, 29 May 1994 09:19:37 GMT
  2974. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  2975.  
  2976. Ken Baer (baer@qiclab.scn.rain.com) wrote:
  2977. : I need to save 32-bit images as PICT files that include the upper 8 bits
  2978. : of data (the alpha buffer).  My code currently saves as 32-bit PICT files,
  2979. : but the upper 8-bit of data are missing!  I am using the methods described
  2980. : in Inside Mac and developer notes.  The sequence I use now is as follows:
  2981. :  - allocate and write 32-bit data to an offscreen GWorld
  2982. :  - OpenPicture()
  2983. :  - CopyBits(offgworld, offgworld) (copy the pixmap to itself)
  2984. :  - ClosePicture()
  2985.  
  2986. : Is there an extra writing step to jam in the alpha buffer?  Is there any
  2987. : sample code (in C) with a more modern method?  The sample code I'm working
  2988. : from is pretty dated.
  2989.  
  2990. Under system 6.0, you could use the upper 8 bits as an alpha channel.
  2991. >From what I understand, that was a bug.
  2992.  
  2993. Current PICT files only support 24-bit images. The upper 8bits are 
  2994. truncated, and the picture is stored as 24-bits per pixel.
  2995.  
  2996. To associate an alpha channel with a PICT, you will need to do some 
  2997. custom stuff. I'm not sure what your application is, but if you are doing 
  2998. everything yuorself, you could store the normal picture as a 24-bit pict 
  2999. file (normal PICT file) and create a PICT resource in that file that 
  3000. contains the alpha channel. This way "normal" applications can use your 
  3001. data-fork PICT file normally, and you can use your alpha channel in your 
  3002. own apps.
  3003.  
  3004. Also, if you are planning on using photoshop, photoshop has a buil-in 
  3005. filter that allows you to take a PICT resource from a file. So your users 
  3006. could still have access to your "custom" alpha channel in photoshop.
  3007.  
  3008. Another alternative is to use the photoshop standard as your file format. 
  3009. The ps format allows for as many channels as you would like. And 
  3010. photoshop is a pretty standard application now, and is widely used.
  3011.  
  3012. Hope this helps.
  3013.  
  3014. Chris Athanas
  3015.  
  3016. +++++++++++++++++++++++++++
  3017.  
  3018. >From baer@qiclab.scn.rain.com (Ken Baer)
  3019. Date: Mon, 30 May 1994 17:51:58 GMT
  3020. Organization: SCN Research/Qic Laboratories of Tigard, Oregon.
  3021.  
  3022. In article <zapper2CqK4Kq.Fn2@netcom.com> zapper2@netcom.com (Chris Athanas) writes:
  3023. >Ken Baer (baer@qiclab.scn.rain.com) wrote:
  3024. >: I need to save 32-bit images as PICT files that include the upper 8 bits
  3025. >: of data (the alpha buffer).  My code currently saves as 32-bit PICT files,
  3026. >: but the upper 8-bit of data are missing!  I am using the methods described
  3027. >: in Inside Mac and developer notes.  The sequence I use now is as follows:
  3028. >:  - allocate and write 32-bit data to an offscreen GWorld
  3029. >:  - OpenPicture()
  3030. >:  - CopyBits(offgworld, offgworld) (copy the pixmap to itself)
  3031. >:  - ClosePicture()
  3032. >
  3033. >: Is there an extra writing step to jam in the alpha buffer?  Is there any
  3034. >: sample code (in C) with a more modern method?  The sample code I'm working
  3035. >: from is pretty dated.
  3036. >
  3037. >Under system 6.0, you could use the upper 8 bits as an alpha channel.
  3038. >From what I understand, that was a bug.
  3039.  
  3040. A damn useful bug.  I guess 32-bit QuickDraw was a typo too :-(.
  3041.  
  3042. >Current PICT files only support 24-bit images. The upper 8bits are 
  3043. >truncated, and the picture is stored as 24-bits per pixel.
  3044.  
  3045. What's the logic behind this?  Or as Seinfeld would say, "Who are the 
  3046. programming wizards that came up with this one?!?"
  3047.  
  3048. >To associate an alpha channel with a PICT, you will need to do some 
  3049. >custom stuff. I'm not sure what your application is, but if you are doing 
  3050. >everything yuorself, you could store the normal picture as a 24-bit pict 
  3051. >file (normal PICT file) and create a PICT resource in that file that 
  3052. >contains the alpha channel. This way "normal" applications can use your 
  3053. >data-fork PICT file normally, and you can use your alpha channel in your 
  3054. >own apps.
  3055.  
  3056. The application in question is a 3D renderer which normally outputs 
  3057. QuickTime (which has no problem dealing with real 32-bit data), but will
  3058. also put out Targa, PICS, and PICT.  I want PICT files with an alpha
  3059. channel that can be used primarily in Photoshop, and in other applications
  3060. that support 32-bit PICT files.
  3061.  
  3062. >Also, if you are planning on using photoshop, photoshop has a buil-in 
  3063. >filter that allows you to take a PICT resource from a file. So your users 
  3064. >could still have access to your "custom" alpha channel in photoshop.
  3065.  
  3066. Are you saying that Photoshop uses the alpha in a resource method that you
  3067. described above?  Is this documented anywhere?
  3068.  
  3069. >
  3070. >Another alternative is to use the photoshop standard as your file format. 
  3071. >The ps format allows for as many channels as you would like. And 
  3072. >photoshop is a pretty standard application now, and is widely used.
  3073.  
  3074. I'd rather stick with PICT, though it is easily my leasy favorite image
  3075. format.  It's really a shame that the Mac standard format is also the
  3076. least portable to other systems.  It's a big deal to us since our
  3077. application also runs on Windows and SGI.
  3078.  
  3079. >
  3080. >Hope this helps.
  3081.  
  3082. Yes, it does.  My big question is what is everyone else doing for saving
  3083. alpha with PICT files?
  3084.  
  3085. >
  3086. >Chris Athanas
  3087.  
  3088.  
  3089. -- 
  3090.  \_       -Ken Baer.  Programmer/Animator, Hash Inc.
  3091. <[_]   Usenet: baer@qiclab.scn.rain.com/AppleLink:KENBAER/Office: (206)750-0042
  3092.  =# \, Animation Master: Finally, 3D animation software an artist can afford!
  3093.  
  3094. +++++++++++++++++++++++++++
  3095.  
  3096. >From scottsquir@aol.com (ScottSquir)
  3097. Date: 30 May 1994 18:54:02 -0400
  3098. Organization: America Online, Inc. (1-800-827-6364)
  3099.  
  3100. In article <1994May30.175158.28837@qiclab.scn.rain.com>,
  3101. baer@qiclab.scn.rain.com (Ken Baer) writes:
  3102.  
  3103. > My big question is what is everyone else doing for saving
  3104. >alpha with PICT files?
  3105.  
  3106. Set the cmpCount in the GWorld pixmap to 4.  It defaults to 3.
  3107.  
  3108. If you resize or do other CopyBits manipulation it may get lost.
  3109. -scott
  3110.  
  3111.  
  3112. +++++++++++++++++++++++++++
  3113.  
  3114. >From Darrin.Cardani@AtlantaGA.NCR.COM (Darrin Cardani)
  3115. Date: Tue, 31 May 1994 18:17:38 GMT
  3116. Organization: UNITY, AT&T GIS
  3117.  
  3118. In article <1994May30.175158.28837@qiclab.scn.rain.com> baer@qiclab.scn.rain.com (Ken Baer) writes:
  3119.  
  3120. >Are you saying that Photoshop uses the alpha in a resource method that you
  3121. >described above?  Is this documented anywhere?
  3122.  
  3123. You can get all the docs on Photoshop's format from archive.umich.edu in the
  3124. mac/graphics/util directory. (Might be mac/development directory, actually, I'm
  3125. not sure).
  3126.  
  3127. >>
  3128. >>Another alternative is to use the photoshop standard as your file format. 
  3129. >>The ps format allows for as many channels as you would like. And 
  3130. >>photoshop is a pretty standard application now, and is widely used.
  3131.  
  3132. >Yes, it does.  My big question is what is everyone else doing for saving
  3133. >alpha with PICT files?
  3134.  
  3135. I'm currently saving them as 2 PICT files. I've debated using 1 file with 2
  3136. PICT resources in it. I think I'll end up using the Photoshop method, because
  3137. it adds usefulness to my program.
  3138.  
  3139. Also, someone mentioned you could have as many channels as needed with the
  3140. photoshop format, I believe you can only have up to 16, though.
  3141.  
  3142. >-- 
  3143. > \_       -Ken Baer.  Programmer/Animator, Hash Inc.
  3144. ><[_]   Usenet: baer@qiclab.scn.rain.com/AppleLink:KENBAER/Office: (206)750-0042
  3145. > =# \, Animation Master: Finally, 3D animation software an artist can afford!
  3146.  
  3147. Really? What it is and can a demo be downloaded anywhere?
  3148.  
  3149. Darrin
  3150.  
  3151. Darrin Cardani
  3152. Opinions above are mine. Mine! Mine! Mine!
  3153. Darrin.Cardani@AtlantaGA.NCR.COM
  3154.  
  3155. +++++++++++++++++++++++++++
  3156.  
  3157. >From a ()
  3158. Date: 2 Jun 1994 01:11:24 GMT
  3159. Organization: Apple Computer, Inc., Cupertino, California
  3160.  
  3161. In article <1994May30.175158.28837@qiclab.scn.rain.com>,
  3162. baer@qiclab.scn.rain.com (Ken Baer) wrote:
  3163.  
  3164. > In article <zapper2CqK4Kq.Fn2@netcom.com> zapper2@netcom.com (Chris Athanas) writes:
  3165. > >Ken Baer (baer@qiclab.scn.rain.com) wrote:
  3166. > >: I need to save 32-bit images as PICT files that include the upper 8 bits
  3167. > >: of data (the alpha buffer).  My code currently saves as 32-bit PICT files,
  3168. > >: but the upper 8-bit of data are missing!  I am using the methods described
  3169. > >: in Inside Mac and developer notes.  The sequence I use now is as follows:
  3170. > >:  - allocate and write 32-bit data to an offscreen GWorld
  3171. > >:  - OpenPicture()
  3172. > >:  - CopyBits(offgworld, offgworld) (copy the pixmap to itself)
  3173. > >:  - ClosePicture()
  3174. > >
  3175. > >: Is there an extra writing step to jam in the alpha buffer?  Is there any
  3176. > >: sample code (in C) with a more modern method?  The sample code I'm working
  3177. > >: from is pretty dated.
  3178. > >
  3179. > >Under system 6.0, you could use the upper 8 bits as an alpha channel.
  3180. > >From what I understand, that was a bug.
  3181. > A damn useful bug.  I guess 32-bit QuickDraw was a typo too :-(.
  3182. > >Current PICT files only support 24-bit images. The upper 8bits are 
  3183. > >truncated, and the picture is stored as 24-bits per pixel.
  3184. > What's the logic behind this?  Or as Seinfeld would say, "Who are the 
  3185. > programming wizards that came up with this one?!?"
  3186. > >To associate an alpha channel with a PICT, you will need to do some 
  3187. > >custom stuff. I'm not sure what your application is, but if you are doing 
  3188. > >everything yuorself, you could store the normal picture as a 24-bit pict 
  3189. > >file (normal PICT file) and create a PICT resource in that file that 
  3190. > >contains the alpha channel. This way "normal" applications can use your 
  3191. > >data-fork PICT file normally, and you can use your alpha channel in your 
  3192. > >own apps.
  3193. > The application in question is a 3D renderer which normally outputs 
  3194. > QuickTime (which has no problem dealing with real 32-bit data), but will
  3195. > also put out Targa, PICS, and PICT.  I want PICT files with an alpha
  3196. > channel that can be used primarily in Photoshop, and in other applications
  3197. > that support 32-bit PICT files.
  3198. > >Also, if you are planning on using photoshop, photoshop has a buil-in 
  3199. > >filter that allows you to take a PICT resource from a file. So your users 
  3200. > >could still have access to your "custom" alpha channel in photoshop.
  3201. > Are you saying that Photoshop uses the alpha in a resource method that you
  3202. > described above?  Is this documented anywhere?
  3203. > >
  3204. > >Another alternative is to use the photoshop standard as your file format. 
  3205. > >The ps format allows for as many channels as you would like. And 
  3206. > >photoshop is a pretty standard application now, and is widely used.
  3207. > I'd rather stick with PICT, though it is easily my leasy favorite image
  3208. > format.  It's really a shame that the Mac standard format is also the
  3209. > least portable to other systems.  It's a big deal to us since our
  3210. > application also runs on Windows and SGI.
  3211. > >
  3212. > >Hope this helps.
  3213. > Yes, it does.  My big question is what is everyone else doing for saving
  3214. > alpha with PICT files?
  3215. > >
  3216. > >Chris Athanas
  3217. > -- 
  3218. >  \_       -Ken Baer.  Programmer/Animator, Hash Inc.
  3219. > <[_]   Usenet: baer@qiclab.scn.rain.com/AppleLink:KENBAER/Office: (206)750-0042
  3220. >  =# \, Animation Master: Finally, 3D animation software an artist can afford!
  3221.  
  3222. The technique is described in IM VI pp 17-22 through 17-23; basically the
  3223. idea is that before calling CopyBits you need to set the packType field in
  3224. the source pixmap to four and the cmpCount to 4 also.
  3225.  
  3226. Hope this really helps.
  3227.  
  3228. Guillermo
  3229.  
  3230. ---------------------------
  3231.  
  3232. >From wingo@apple.com (Tony Wingo)
  3233. Subject: Open Transport & ASLM
  3234. Date: Thu, 2 Jun 1994 18:06:30 GMT
  3235. Organization: Apple Computer
  3236.  
  3237. The following is a response from the Open Transport Team to the recent
  3238. threads on OpenTransport, ASLM and DLL's in general.
  3239.  
  3240. Comments may be sent to opentpt@applelink.apple.com
  3241.  
  3242. =====================================================================
  3243.  
  3244. When Open Transport was developed, ASLM was the only general option
  3245. for dynamic linking - CFM and SOM were not anywhere in sight. In
  3246. fact, today we still can only use CFM for dynamic linking on PowerPC.
  3247. It's not available for 68K, and SOM is not available for either
  3248. platform.
  3249.  
  3250. Whether or not ASLM is used as the dynamic linking mechanism, the
  3251. fact that C++ objects generated by different compilers have different
  3252. formats makes it virtually impossible to export object-oriented
  3253. interfaces that everyone can use.  Yes - SOM will solve this problem,
  3254. but that solution does not come without a performance penalty -
  3255. parameters have to be marshalled, and solving the fragile base class
  3256. problem requires a much more indirect method of dispatching than a
  3257. jump through a vtable.  
  3258.  
  3259. We really wanted to be able to create an object-oriented framework
  3260. for writing STREAMS modules, and ASLM allowed us to do that without a
  3261. performance penalty.   Now that CFM and SOM are either here or on the
  3262. horizon, we've backed off of that goal.
  3263.  
  3264. >From a client perspective, Open Transport supports a complete
  3265. procedural interface using Pascal calling conventions for use in the
  3266. widest range of development environments possible.  It also has a C++
  3267. object interface, which is usable with MPW Cfront, and with the PPCC
  3268. Script/tools for PowerPC.  We believe that the C++ interface is also
  3269. usable from Symantec C++ for 68K, but this has not been tested. We
  3270. have also not tested with the Metrowerks products, but are assuming
  3271. that, like Symantec, they have a way to import MPW .o and XCOFF
  3272. files.
  3273.  
  3274. ASLM is currently used as the dynamically loading mechanism for both
  3275. client code and STREAMS modules, but neither version REQUIRES using
  3276. C++ interface.  
  3277.  
  3278. When SOM becomes available as part of the system, we will look at
  3279. converting our C++ client interfaces to become SOM objects.  The
  3280. procedural interfaces for STREAMS modules will remain ASLM-based for
  3281. 68K and CFM-based for PowerPC.
  3282.  
  3283. The bottom line is:  If you can't get Open Transport client files to
  3284. link with your tools using our "C" interfaces, then either your tools
  3285. don't support MPW-generated libraries,  your tools can't deal with
  3286. Pascal calling conventions, or the Open Transport team has a bug.
  3287.  
  3288. We have not yet published any information on how to write a STREAM
  3289. module for Open Transport.  As soon as we do, it will tell you how to
  3290. create both ASLM and CFM-based STREAM modules.
  3291.  
  3292. I hope this clears up any misunderstandings on using Open Transport.
  3293.  
  3294. ---------------------------
  3295.  
  3296. >From kennedy@fenton.cs.udcavis.edu (Kennedy)
  3297. Subject: Sending the Mac Screen Image
  3298. Date: Thu, 2 Jun 1994 01:56:33 GMT
  3299. Organization: University of California, Davis
  3300.  
  3301.  
  3302.     This might be too involved of a question for this news group
  3303. But I was wondering if anyone had any Ideas. What I need to do is 
  3304. send screen image of a Macintosh so that it can be viewed in all
  3305. its glory in an X window. The screen should refresh flicker free
  3306. and should look to the viewer of the X window as is he/she was 
  3307. looking at the Mac monitor. This has to be done using TCP/IP. 
  3308.      If you have any Ideas, example code, algorithms, or whether 
  3309. you think it can be done or not, let me know. Thanx.
  3310.  
  3311. Brian Kennedy (kennedy@fenton.cs.ucdavis.edu)
  3312.  
  3313.  
  3314. +++++++++++++++++++++++++++
  3315.  
  3316. >From rmah@panix.com (Robert S. Mah)
  3317. Date: Thu, 02 Jun 1994 01:22:22 -0500
  3318. Organization: One Step Beyond
  3319.  
  3320. kennedy@fenton.cs.udcavis.edu (Kennedy) wrote:
  3321.  
  3322. >     This might be too involved of a question for this news group
  3323. > But I was wondering if anyone had any Ideas. What I need to do is 
  3324. > send screen image of a Macintosh so that it can be viewed in all
  3325. > its glory in an X window. The screen should refresh flicker free
  3326. > and should look to the viewer of the X window as is he/she was 
  3327. > looking at the Mac monitor. This has to be done using TCP/IP. 
  3328. >      If you have any Ideas, example code, algorithms, or whether 
  3329. > you think it can be done or not, let me know. Thanx.
  3330.  
  3331. Since you said "in all its glory" I take it you mean color.
  3332.  
  3333. Let's see...640x480 minimum screen size means 300K per frame.  At 24 fps,
  3334. that's around 7MBytes per second.  Too much.
  3335.  
  3336. You'll have to send screen differences (i.e. just what changed on the 
  3337. screen) to get a decent frame rate.  Keep a copy of the screen image on
  3338. the Mac, note the changes, send it via TCP/IP.  Receive it on the UNIX 
  3339. machine.  Have the X Server send it to the X Client.
  3340.  
  3341. You could also patch all of QuickDraw and send the QD command opcodes to
  3342. the UNIX box.  There, you'd have to write a QD emulator and execute the
  3343. opcodes as they come in.  This would be very hard to write, but would 
  3344. work faster than the screen difference method.
  3345.  
  3346. Have you considered just buying it.  I think there are a few products 
  3347. that do this out there.
  3348.  
  3349. Cheers,
  3350. Rob
  3351. ___________________________________________________________________________
  3352. Robert S. Mah  -=-  One Step Beyond  -=-  212-947-6507  -=-  rmah@panix.com
  3353.  
  3354. +++++++++++++++++++++++++++
  3355.  
  3356. >From David K}gedal <davidk@lysator.liu.se>
  3357. Date: 2 Jun 1994 11:44:58 GMT
  3358. Organization: Lysator Academic Computer Society
  3359.  
  3360. In article <rmah-020694012222@rmah.dialup.access.net> Robert S. Mah,
  3361. rmah@panix.com writes:
  3362. >You'll have to send screen differences (i.e. just what changed on the 
  3363. >screen) to get a decent frame rate.  Keep a copy of the screen image on
  3364. >the Mac, note the changes, send it via TCP/IP.  Receive it on the UNIX 
  3365. >machine.  Have the X Server send it to the X Client.
  3366.  
  3367. Oops, this is a very common confusion. It is of course the X client that 
  3368. will send it to the X server. The server is the one that controls the 
  3369. actual screen and does the drawing that the clients tells it to do.
  3370.  
  3371.  /David
  3372.  
  3373. +++++++++++++++++++++++++++
  3374.  
  3375. >From d88-jwa@mumrik.nada.kth.se (Jon Wdtte)
  3376. Date: 2 Jun 1994 12:56:48 GMT
  3377. Organization: The Royal Institute of Technology
  3378.  
  3379. In <rmah-020694012222@rmah.dialup.access.net> rmah@panix.com (Robert S. Mah) writes:
  3380.  
  3381. >Let's see...640x480 minimum screen size means 300K per frame.  At 24 fps,
  3382. >that's around 7MBytes per second.  Too much.
  3383.  
  3384. You only need send what's drawn, and you can compress it while you
  3385. send.
  3386.  
  3387. There are commercial apps that do EXACTLY this. There are two
  3388. mechanisms you can use; patching the QuickDraw bottlenecks, or
  3389. patching ShieldCursor().
  3390.  
  3391. QuickDraw does all drawing through bottlenecks, so if you want
  3392. object graphics, send the bottleneck commands across the network.
  3393. You have to send port information as well, I guess.
  3394.  
  3395. QuickDraw also calls ShieldCursor() for the enclosing rectangle of
  3396. what it draws, and ShowCursor() when it's done, so if you only
  3397. want a bitmap, use that area, and send the (packed) bitmap once
  3398. drawing is done (ShowCursor() time) or accumulate it all into a
  3399. region which you send at WaitNextEvent time.
  3400. -- 
  3401.  -- Jon W{tte, h+@nada.kth.se, Mac Software Engineer Deluxe --
  3402.    This signature is kept shorter than 4 lines in the interests of UseNet
  3403.    S/N ratio.
  3404.  
  3405. +++++++++++++++++++++++++++
  3406.  
  3407. >From rmah@panix.com (Robert S. Mah)
  3408. Date: Thu, 02 Jun 1994 11:40:51 -0500
  3409. Organization: One Step Beyond
  3410.  
  3411. David K}gedal <davidk@lysator.liu.se> wrote:
  3412.  
  3413. > Robert S. Mah, rmah@panix.com writes:
  3414. > >You'll have to send screen differences (i.e. just what changed on the 
  3415. > >screen) to get a decent frame rate.  Keep a copy of the screen image on
  3416. > >the Mac, note the changes, send it via TCP/IP.  Receive it on the UNIX 
  3417. > >machine.  Have the X Server send it to the X Client.
  3418. > Oops, this is a very common confusion. It is of course the X client that 
  3419. > will send it to the X server. The server is the one that controls the 
  3420. > actual screen and does the drawing that the clients tells it to do.
  3421.  
  3422. Right.  I don't do X, so I'm more than a bit hazy about this stuff, but
  3423. after you mentioned it, I did recall reading an article about this and
  3424. saying to myself, "That's supposed to make sense?"
  3425.  
  3426. So, to correct myself...the X-client would ask the X-server to draw the
  3427. stuff.  Hey...couldn't you simply put the X-client on the Mac?  Could
  3428. be an interesting academic project.
  3429.  
  3430. Cheers,
  3431. Rob
  3432. ___________________________________________________________________________
  3433. Robert S. Mah  -=-  One Step Beyond  -=-  212-947-6507  -=-  rmah@panix.com
  3434.  
  3435. ---------------------------
  3436.  
  3437. >From jaffe@rabbit.cita.utoronto.ca (Andrew Jaffe)
  3438. Subject: What are Universal Headers?
  3439. Date: Thu, 19 May 1994 13:49:41 GMT
  3440. Organization: CITA
  3441.  
  3442.  
  3443. That's about it:
  3444.     What are the Universal Headers?
  3445.  
  3446. AJ
  3447. --
  3448. - --------------------------------------------------------------------
  3449. Andrew Jaffe                    jaffe@cita.utoronto.ca
  3450. CITA, U. Toronto                (416) 978-8497, 6879
  3451. 60 Saint George St.                         -3921 (Fax)
  3452. Toronto, ON M5S 1A1 CANADA            
  3453.  
  3454. +++++++++++++++++++++++++++
  3455.  
  3456. >From dean@genmagic.com (Dean Yu)
  3457. Date: 19 May 1994 17:20:31 GMT
  3458. Organization: General Magic, Inc.
  3459.  
  3460. In article <JAFFE.94May19094941@rabbit.cita.utoronto.ca>,
  3461. jaffe@rabbit.cita.utoronto.ca (Andrew Jaffe) wrote:
  3462. > That's about it:
  3463. >     What are the Universal Headers?
  3464.  
  3465.   Universal Headers are the twisted idea of a couple of system software
  3466. engineers who have since left the company to try to avoid the proliferation
  3467. of interface files as the Mac API was going cross platform. That is, rather
  3468. than having a set of header files you compile with if you were doing say a
  3469. PowerPC application, and different set you use if you were doing a 68K
  3470. application, you would have one set that can be used for any platform that
  3471. supplied the Mac API by flipping a couple of compile time switches.
  3472.   Like any grand unifying theory, it was very elusive, long in the coming,
  3473. and probably a little less all-encompassing than it should have been.
  3474.  
  3475. -- Dean Yu
  3476.    Negative Ethnic Role Model
  3477.    General Magic, Inc.
  3478.  
  3479. +++++++++++++++++++++++++++
  3480.  
  3481. >From Lars.Farm@nts.mh.se (Lars Farm)
  3482. Date: Fri, 20 May 1994 09:43:17 +0100
  3483. Organization: Mid Sweden University
  3484.  
  3485. In article <dean-190594101355@dean_yu.genmagic.com>, dean@genmagic.com
  3486. (Dean Yu) wrote:
  3487.  
  3488. > In article <JAFFE.94May19094941@rabbit.cita.utoronto.ca>,
  3489. > jaffe@rabbit.cita.utoronto.ca (Andrew Jaffe) wrote:
  3490. > > 
  3491. > > That's about it:
  3492. > >     What are the Universal Headers?
  3493. > > 
  3494. >   Universal Headers are the twisted idea of a couple of system software
  3495. [...]
  3496. >   Like any grand unifying theory, it was very elusive, long in the coming,
  3497. > and probably a little less all-encompassing than it should have been.
  3498.  
  3499. Still, it is very nice to have _one_ set of Mac headers, after all there is
  3500. only one API. Now it's a lot simpler to move code between compilers. This
  3501. can't be bad.
  3502.  
  3503. -- 
  3504. Lars.Farm@nts.mh.se
  3505.  
  3506. +++++++++++++++++++++++++++
  3507.  
  3508. >From slosser@apple.com (Eric Slosser)
  3509. Date: Sat, 28 May 1994 21:14:40 GMT
  3510. Organization: Apple Computer, Inc.
  3511.  
  3512. > In article <dean-190594101355@dean_yu.genmagic.com>, dean@genmagic.com
  3513. > (Dean Yu) wrote:
  3514. > > 
  3515. > >   Universal Headers are the twisted idea of a couple of system software
  3516. > [...]
  3517. > >   Like any grand unifying theory, it was very elusive, long in the coming,
  3518. > > and probably a little less all-encompassing than it should have been.
  3519.  
  3520. Well, with the kind of people they had working on the project, what did you
  3521. expect, Dean?
  3522.  
  3523. PS.  Don't forget the really novel idea of having the C, Pascal, and Asm
  3524. headers auto-generated from a master file, rather than maintained by hand.
  3525.  
  3526. -- 
  3527. Eric Slosser / Apple Computer / slosser@apple.com
  3528.  
  3529. +++++++++++++++++++++++++++
  3530.  
  3531. >From jum@anubis.han.de (Jens-Uwe Mager)
  3532. Date: Thu, 2 Jun 94 01:05:11 MET
  3533. Organization: (none)
  3534.  
  3535.  
  3536. In article <slosser-280594131440@mac96.kip.apple.com> (comp.sys.mac.programmer), slosser@apple.com (Eric Slosser) writes:
  3537.  
  3538. > PS.  Don't forget the really novel idea of having the C, Pascal, and Asm
  3539. > headers auto-generated from a master file, rather than maintained by hand.
  3540.  
  3541.  
  3542. Hmmm, how does your specification language look like?
  3543.  
  3544. ______________________________________________________________________________
  3545. Jens-Uwe Mager            jum@anubis.han.de
  3546. 30177 Hannover            jum@helios.de
  3547. Brahmsstr. 3            Tel.: +49 511 660238
  3548.  
  3549. ---------------------------
  3550.  
  3551. End of C.S.M.P. Digest
  3552. **********************
  3553.  
  3554.  
  3555.