cjr20670@uxa.cso.uiuc.edu (06/19/89)
I recently wrote a nifty do-dad program that some of you might have seen.
It's called GDraw; it basically just whipped dots around the screen in
facinating paths. I'm now working on version 2, but I've run across
a problem that I can't figure a way around.
One of the more complicated new features I'm adding is the ability to
switch math modes on the fly, for example from Fixed to SANE. Presently,
this is all it can do. I had planned to also add Direct 881 access, BUT
LightSpeed C is giving me qualms.
All the floating numbers are using this struct at present:
typedef struct
{
double sn; /* SANE number */
Fixed fx; /* Fixed number */
} aNum;
So that's the first big problem, how do I put the 881 "double" in the
same struct? They're both called double, but one is 12 bytes and the other
is 10 bytes. I can't specify one without the other. Gggrrrrr.
If someone can help me with that problem, I've got another one for ya.
Is there anyway I can use both the Math and Math881 libraries in the SAME
project without renaming the needed functions in one of the libraries?
Anyone with experience in mixing oil and water, please help!
Charlie Reiman
creiman@ncsa.uiuc.edu
cjr20670@uxa.cso.uiuc.edu
"My keyboard's busted. It keeps misspelling words."
My boss
siegel@endor.harvard.edu (Rich Siegel) (06/20/89)
In article <227700009@uxa.cso.uiuc.edu> cjr20670@uxa.cso.uiuc.edu writes: > All the floating numbers are using this struct at present: > >typedef struct > { > double sn; /* SANE number */ > Fixed fx; /* Fixed number */ > } aNum; > > So that's the first big problem, how do I put the 881 "double" in the >same struct? They're both called double, but one is 12 bytes and the other >is 10 bytes. I can't specify one without the other. Gggrrrrr. You could put 96-bit doubles in your struct by typedef'ing them as a 12-character array, or three longs. (This is assuming non-881 code generation.) > If someone can help me with that problem, I've got another one for ya. >Is there anyway I can use both the Math and Math881 libraries in the SAME >project without renaming the needed functions in one of the libraries? Nope. The current design of the linker doesn't allow multiple or overriding routine definitions, and at any rate, how would you know which routines to call? > Anyone with experience in mixing oil and water, please help! Mixing 80- and 96-bit arithmetic in the same program is not something to be undertake lightly, if at all. You might consider two copies of your program - one for SANE use, one for direct 881 use. In My Humble Opinion, someone Screwed Up when making doubles to be 80 bits. Motorola has some moderately reasonable reason for making the IEEE Extended type a 12-byte type, to wit, longword alignment. I think the SANE interfaces could have been designed this way, but it's kind of too late.... GDraw is a nifty program. If you haven't seen it, take a look. --Rich ~~~~~~~~~~~~~~~ Rich Siegel Staff Software Developer Symantec Corporation, Language Products Group Internet: siegel@endor.harvard.edu UUCP: ..harvard!endor!siegel I classify myself as a real developer because my desk is hip-deep in assembly-language listings and I spend more than 50% of my time in TMON. ~~~~~~~~~~~~~~~
earleh@eleazar.dartmouth.edu (Earle R. Horton) (06/20/89)
In article <2089@husc6.harvard.edu> siegel@endor.UUCP (Rich Siegel) writes: ... > In My Humble Opinion, someone Screwed Up when making doubles >to be 80 bits. Motorola has some moderately reasonable reason for making >the IEEE Extended type a 12-byte type, to wit, longword alignment. >I think the SANE interfaces could have been designed this way, but it's >kind of too late.... Actually, double is 64 bits. SANE defines four data types: Single, double, computational, and extended have 32, 64, 64, and 80 bits respectively. MPW is the only C compiler I know of which lets you have all four types at the compiler level. Aztec maps extended to double, and from what you say TLSC maps double to extended. (I am using the SANE definition of double here. One could argue that the way C defines double actually implies IEEE Extended.) One option is to use SANE single or double for storage, and let SANE or the 881 do the calculations in extended. This is kind of rough in a high-level language, and there is a speed penalty when using non-extended types. Actually, since the first Mac had 128k of RAM, I would say that Apple had a fairly reasonable reason for storing extended in 80 bits. Kind of like storing flags in the high bits of master pointers. Earle R. Horton "People forget how fast you did a job, but they remember how well you did it." Salada Tag Lines
trebor@biar.UUCP (Robert J Woodhead) (06/20/89)
In article <227700009@uxa.cso.uiuc.edu> cjr20670@uxa.cso.uiuc.edu writes: > I recently wrote a nifty do-dad program that some of you might have seen. >It's called GDraw; it basically just whipped dots around the screen in >facinating paths. This sounds like it would make a wonderful ``NightLife'' screensaver. I've been beta-testing NightLife (it will be, imho, the best screensaver of the bunch) and it is _very_ easy to write your own screensaver module for the program. ``NightLife'', in case you don't know, is basically a ScreenSaver ``shell.'' It lets you choose which ``effect'' you want to use, and you can program your own. Mine has worms crawling around the screen eating pixels. -- (^;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-;^) Robert J Woodhead, Biar Games, Inc. !uunet!biar!trebor | trebor@biar.UUCP ``I can read your mind - right now, you're thinking I'm full of it...''
shebanow@apple.com (Andrew Shebanow) (06/21/89)
In article <227700009@uxa.cso.uiuc.edu> cjr20670@uxa.cso.uiuc.edu writes: > So that's the first big problem, how do I put the 881 "double" in the > same struct? They're both called double, but one is 12 bytes and the other > is 10 bytes. I can't specify one without the other. Gggrrrrr. For LSC, I recommend that you use the "short double" type (64 bits) in your data structures instead of double. You probably don't need the extra precision, and this data type is the same whether you have an 881 or not. The only disadvantage is that SANE is slower on 64 bit operations than it is on 80 bit (96 for 881) operations, since it has to convert the operands to 80 bit before doing its calculations. You can get around this limitation by caching the extended versions of your numbers inside of complex calculations. As far as using 881 and non-881 libraries together goes, you are going to have a tough job. What I recommend is that you compile everything without the 881 option turned on, and that you isolate (and minimize) your floating point library calls. For each library call you want to use, write a wrapper function like this: extern Boolean haveFPU; typedef short double96[6]; double myLibraryCall(double a, double b) { double96 tmpA, tmpB, tmpRes; double res; if (haveFPU) { x80tox96(&a,tmpA); x80tox96(&b,tmpB); asm { /* * do the whole thing in assembler, using FPU instructions * Move tmpA and tmpB into FPU registers, store result in tmpRes */ }; x96tox80(tmpRes,&res); return res; } else return RealLibraryCall(a,b); } You will have to write the routines x80tox96 and x96tox80 yourself, but they aren't that tough - just bitshift things around (BTW, MPW 3.0 includes these routines). This whole solution is ugly, but it should work. Disclaimer: I've done this on a small scale in MPW 3.0, so I know it can be done, but I haven't tried it in LSC, so there may be some unexpected problems. Have fun, Andrew Shebanow MacDTS - Wanna See Something REALLY Scary? -
siegel@endor.harvard.edu (Rich Siegel) (06/21/89)
In article <14001@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu (Earle R. Horton) writes: > Actually, double is 64 bits. SANE defines four data types: >Single, double, computational, and extended have 32, 64, 64, and 80 >bits respectively. MPW is the only C compiler I know of which lets >you have all four types at the compiler level. Aztec maps extended to >double, and from what you say TLSC maps double to extended. (I am Sorry about that - I meant 'extended', but my fingers were still thinking C. In TLSC, the 'double' data type is 80-bit (or 96-bit, depending on options) SANE Extended, and 'short double' is the 64-bit IEEE double-precision data type. > Actually, since the first Mac had 128k of RAM, I would say that >Apple had a fairly reasonable reason for storing extended in 80 bits. >Kind of like storing flags in the high bits of master pointers. What does that have to do with the price of tea in China? I don't follow the correlation. -R. ~~~~~~~~~~~~~~~ Rich Siegel Staff Software Developer Symantec Corporation, Language Products Group Internet: siegel@endor.harvard.edu UUCP: ..harvard!endor!siegel I classify myself as a real developer because my desk is hip-deep in assembly-language listings and I spend more than 50% of my time in TMON. ~~~~~~~~~~~~~~~
lippin@spam.berkeley.edu (The Apathist) (06/21/89)
Recently cjr20670@uxa.cso.uiuc.edu wrote: [...] > I recently wrote a nifty do-dad program that some of you might have seen. >It's called GDraw; it basically just whipped dots around the screen in >facinating paths. I'm now working on version 2, but I've run across >a problem that I can't figure a way around. > One of the more complicated new features I'm adding is the ability to >switch math modes on the fly, for example from Fixed to SANE. Presently, >this is all it can do. I had planned to also add Direct 881 access, BUT >LightSpeed C is giving me qualms. Types are pretty easy -- since you don't need to see the inside of a number, you can declare a struct of the appropriate length to be the extended size you don't have. As for the math library, I say ditch it. It isn't really doing much, and it's going to get in your way. Instead, get to the SANE routines through fp68k() and elems68k(). There's a header file <sane.h> in LSC that contains most of what you need; the Apple Numerics manual will tell you how to use it, sort of. To get you started, here are some sample uses: Given extended a,b, b+=a fp68k(&a,&b,FOADD|FFEXT) a=sin(a) elems68k(&a,FOSIN|FFEXT) (This is from memory; you can check me against the source for the math library.) It may be handy to make a set of macro definitions for these calls. Once you understand how to use SANE, you have two options. The "no guts" way is to use the Math881 library for the 881 calls; there's no insurmountable problem with this now that you don't use the regular math library. But you will have to live with double being 96 bits and convert as necessary. Also, be careful not to use any of the C operators for +-/*=<> on floating point numbers in places where you might be running without an FPU. Finally, this will add a subroutine jump/return to each operation, which may be noticeable when you're running on the FPU. The "guts" way is to write the assembler for elementary operations yourself, and probably include them as macros, like this: #ifdef useFPU #define sin(a) asm{ fsin a } #else #define sin(a) elems68k(&a,FOSIN,FFEXT) #endif Then you can stick your floating point intensive routines in a separate file, and make two copies, one defining useFPU and one not. Of course, you'll still have to use two different names, and convert any floating point numbers where these modules communicate with the main program. Good luck, and may the source be with you, --Tom Lippincott lippin@math.berkeley.edu "You've got to know when to code it, know when to log out, know when to single step, know when to run..." --The Hacker
earleh@eleazar.dartmouth.edu (Earle R. Horton) (06/21/89)
In article <2092@husc6.harvard.edu> siegel@endor.UUCP (Rich Siegel) writes: >In article <14001@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu (Earle R. Horton) writes: ... >> Actually, since the first Mac had 128k of RAM, I would say that >>Apple had a fairly reasonable reason for storing extended in 80 bits. >>Kind of like storing flags in the high bits of master pointers. > > What does that have to do with the price of tea in China? >I don't follow the correlation. Well, by storing extended in 80 bits versus 96 bits, you save 16 bits per floating point quantity. By storing flags in the high bits of master pointers, you save at least 16 bits over doing it the right way. I suppose it is a weak correlation, at that. Earle R. Horton "People forget how fast you did a job, but they remember how well you did it." Salada Tag Lines
siegel@endor.harvard.edu (Rich Siegel) (06/21/89)
In article <14017@dartvax.Dartmouth.EDU> earleh@eleazar.dartmouth.edu (Earle R. Horton) writes: > Well, by storing extended in 80 bits versus 96 bits, you save 16 >bits per floating point quantity. By storing flags in the high bits of You're technicaly correct, but it's a pretty weak reason to have made the size what it was (if, in fact, that WAS the reason). If you're that concerned about space, store your results as single, and use extendeds for temps (which most compilers do for calculations). --R. ~~~~~~~~~~~~~~~ Rich Siegel Staff Software Developer Symantec Corporation, Language Products Group Internet: siegel@endor.harvard.edu UUCP: ..harvard!endor!siegel I classify myself as a real developer because my desk is hip-deep in assembly-language listings and I spend more than 50% of my time in TMON. ~~~~~~~~~~~~~~~