Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site ecsvax.UUCP Path: utzoo!watmath!clyde!bonnie!akgua!mcnc!ecsvax!bet From: bet@ecsvax.UUCP (Bennett E. Todd III) Newsgroups: net.lang.c Subject: Doing complex math in C Message-ID: <576@ecsvax.UUCP> Date: Tue, 15-Oct-85 14:04:48 EDT Article-I.D.: ecsvax.576 Posted: Tue Oct 15 14:04:48 1985 Date-Received: Fri, 18-Oct-85 01:42:09 EDT Reply-To: duccpc!bet@ecsvax.UUCP (Bennett E. Todd III) Distribution: net Organization: Duke University Computation Center Lines: 49 In net.math someone asked how you go about clobbering a cubic. Turns out there is a nice closed-form solution. So I looked it up and wrote a trivial little program to solve the cubic. I like C, so I wrote it in C. C doesn't have a complex data type, and doesn't seem inclined to encourage me to write a support library -- in particular, without operator overloading the resulting syntax is vaguely reminiscent of publication LISP syntax, and makes for excessively verbose expressions. Oh well said I, that can be lived with. Turns out I dislike structure passing and return, and think it shouldn't have been added to the language in the first place. (I consider structs to be aggragates just like arrays; references to the name of a struct should be resolved into pointers to that struct). So I didn't use struct passing and return. My complex library routines take as arguments one or more pointers to complex structs, and return a pointer to a complex struct containing the result. Unfortunately, something like C_plus(Complex(1.0, 0.0), Complex(0.0, 1.0)) (Complex() returns a pointer to a struct initialized to the values specified, C_plus() returns a pointer to a struct containing the sum of the two structs passed in.) will drop the two intermediate structs containing the two "constants" on the floor -- they will not be pointed to by anything. Rather than implement a garbage collector, or force all computations to go through temporary variables which can then be freed, I decided to make all the complex routines free any complex args they are passed. Thus if you want to pass a program variable to a complex routine, you must make a copy -- the utility routine C_copy() returns a copy of its arg (which it doesn't free). Well, the end result is that there is a hefty amount of overhead, though not intolerable for light work, and largely optimizable by a sufficiently good compiler. The code ends up being reasonably clear, except for the sort-of-prefix functional notation for expressions. The semantics of these routines is as far as I know unique. Comments? The program (and the complex support library I created) can be found in net.sources. -Bennett -- "Hypocrisy is the vaseline of social intercourse." (Who said that?) Bennett Todd -- Duke Computation Center, Durham, NC 27706-7756; (919) 684-3695 UUCP: ...{decvax,seismo,philabs,ihnp4,akgua}!mcnc!ecsvax!duccpc!bet