424,984 Members | 997 Online
Need help? Post your question and get tips & solutions from a community of 424,984 IT Pros & Developers. It's quick & easy.

# operations on complex numbers in C99

 P: n/a I understand that C99 supports a complex type and complex arithmetic. There is nothing about it in the FAQ and online searches turned up very little except synopses. Can anyone point me toward sources or give examples which show how to: -declare a complex variable -assign the real and imaginary parts -perform the basic +,-,*,/ operations on complex numbers Thanks, David Aug 5 '07 #1
27 Replies

 P: n/a David Marsh wrote: I understand that C99 supports a complex type and complex arithmetic. There is nothing about it in the FAQ and online searches turned up very little except synopses. Can anyone point me toward sources or give examples which show how to: -declare a complex variable -assign the real and imaginary parts -perform the basic +,-,*,/ operations on complex numbers The only examples I have seen are in Annex G of the standard, not the best (being in standards speak!), but they should be enough to get you going. -- Ian Collins. Aug 6 '07 #2

 P: n/a David Marsh . -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Aug 6 '07 #3

 P: n/a David Marsh wrote: > I understand that C99 supports a complex type and complex arithmetic. There is nothing about it in the FAQ and online searches turned up very little except synopses. Can anyone point me toward sources or give examples which show how to: -declare a complex variable -assign the real and imaginary parts -perform the basic +,-,*,/ operations on complex numbers Try N1124 and/or N869. You can get N869 in BZ2'd text form from: -- "Vista is finally secure from hacking. No one is going to 'hack' the product activation and try and steal the o/s. Anyone smart enough to do so is also smart enough not to want to bother." -- Posted via a free Usenet account from http://www.teranews.com Aug 6 '07 #4

 P: n/a Ian Collins wrote: David Marsh wrote: >>I understand that C99 supports a complex type and complex arithmetic.There is nothing about it in the FAQ and online searches turned up verylittle except synopses. Can anyone point me toward sources or giveexamples which show how to:-declare a complex variable-assign the real and imaginary parts-perform the basic +,-,*,/ operations on complex numbers The only examples I have seen are in Annex G of the standard, not the best (being in standards speak!), but they should be enough to get you going. Sheesh! Much easier to write my own library than to make sense of that gobbledygook. But thanks anyway. David Aug 6 '07 #5

 P: n/a David Marsh wrote: I understand that C99 supports a complex type and complex arithmetic. There is nothing about it in the FAQ and online searches turned up very little except synopses. Can anyone point me toward sources or give examples which show how to: -declare a complex variable double _Complex myvar = 5.778 + 45.87*I; (standard notation) Some compilers like lcc-win32 or gcc use double _Complex myvar = 5.778 + 45.87i; but that is not standard. -assign the real and imaginary parts creal(myvar)=8.0; cimag(myvar)=6.9; -perform the basic +,-,*,/ operations on complex numbers (myvar+2)/(myvar-4) Nothing special > Thanks, David Aug 6 '07 #6

 P: n/a David Marsh wrote: Ian Collins wrote: >David Marsh wrote: >>I understand that C99 supports a complex type and complex arithmetic.There is nothing about it in the FAQ and online searches turned up verylittle except synopses. Can anyone point me toward sources or giveexamples which show how to:-declare a complex variable-assign the real and imaginary parts-perform the basic +,-,*,/ operations on complex numbers The only examples I have seen are in Annex G of the standard, not thebest (being in standards speak!), but they should be enough to get yougoing. Sheesh! Much easier to write my own library than to make sense of that gobbledygook. But thanks anyway. David See my answer elsethread. It is very easy. Aug 6 '07 #7

 P: n/a jacob navia wrote: David Marsh wrote: >I understand that C99 supports a complex type and complex arithmetic.There is nothing about it in the FAQ and online searches turned upvery little except synopses. Can anyone point me toward sources orgive examples which show how to:-declare a complex variable double _Complex myvar = 5.778 + 45.87*I; (standard notation) Some compilers like lcc-win32 or gcc use double _Complex myvar = 5.778 + 45.87i; but that is not standard. >-assign the real and imaginary parts creal(myvar)=8.0; cimag(myvar)=6.9; >-perform the basic +,-,*,/ operations on complex numbers (myvar+2)/(myvar-4) Nothing special Thanks, Jacob, but I'm having a problem with the assignments using creal() and cimag(). It works OK if the commented out lines are used instead. What am I doing wrong? David #include #include int main(void) { //double _Complex z1 = 1.2 + .5 * I; //double _Complex z2, z3; double _Complex z1, z2, z3; creal(z1) = 1.2; /* error */ cimag(z1) = .5; /* error */ z2 = csqrt(z1); z3 = z1 + z2; printf("sqrt = %g %gi\n", creal(z2), cimag(z2)); printf("z1+z2 = %g %gi\n", creal(z3), cimag(z3)); return 0; } C:\WINDOWS\Desktop\data>lcc cxtest.c Error cxtest.c: 10 the left hand side of the assignment can't be assigned to Error cxtest.c: 11 the left hand side of the assignment can't be assigned to 2 errors, 0 warnings Aug 6 '07 #8

 P: n/a On Mon, 06 Aug 2007 16:00:22 +0200, jacob navia wrote: David Marsh wrote: >I understand that C99 supports a complex type and complex arithmetic.There is nothing about it in the FAQ and online searches turned up verylittle except synopses. Can anyone point me toward sources or giveexamples which show how to:-declare a complex variable double _Complex myvar = 5.778 + 45.87*I; (standard notation) >-assign the real and imaginary parts creal(myvar)=8.0; cimag(myvar)=6.9; I don't understand the last two. Isn't creal a function returning a double? How can that yield an lvalue?. To set just the real part of myvar, wouldn't you have to write something like myvar = 8.0 + cimag(myvar)*I; ? (For what its worth I much prefer gcc's __real__ and __imag__ operators; with them you can write __real__ myvar = 0.0; ) Aug 6 '07 #9

 P: n/a jacob navia I understand that C99 supports a complex type and complexarithmetic. There is nothing about it in the FAQ and online searchesturned up very little except synopses. Can anyone point me towardsources or give examples which show how to:-declare a complex variable double _Complex myvar = 5.778 + 45.87*I; (standard notation) If you have '#include ' (which is required for 'I' anyway), you can use 'complex' rather than '_Complex'. Some compilers like lcc-win32 or gcc use double _Complex myvar = 5.778 + 45.87i; but that is not standard. and is therefore irrelevant unless you want to make your code gratuitously non-portable. >-assign the real and imaginary parts creal(myvar)=8.0; cimag(myvar)=6.9; creal() and cimag() are functions, which therefore do not yield lvalues. You can't assign to them. >-perform the basic +,-,*,/ operations on complex numbers (myvar+2)/(myvar-4) -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Aug 6 '07 #10

 P: n/a On Aug 7, 9:59 am, Keith Thompson

 P: n/a Old Wolf jacob navia San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Aug 7 '07 #12

 P: n/a David Marsh wrote: jacob navia wrote: >David Marsh wrote: >>I understand that C99 supports a complex type and complex arithmetic.There is nothing about it in the FAQ and online searches turned upvery little except synopses. Can anyone point me toward sources orgive examples which show how to:-declare a complex variable double _Complex myvar = 5.778 + 45.87*I;(standard notation)Some compilers like lcc-win32 or gcc usedouble _Complex myvar = 5.778 + 45.87i;but that is not standard. >>-assign the real and imaginary parts creal(myvar)=8.0;cimag(myvar)=6.9; >>-perform the basic +,-,*,/ operations on complex numbers (myvar+2)/(myvar-4)Nothing special Thanks, Jacob, but I'm having a problem with the assignments using creal() and cimag(). It works OK if the commented out lines are used instead. What am I doing wrong? David #include #include int main(void) { //double _Complex z1 = 1.2 + .5 * I; //double _Complex z2, z3; double _Complex z1, z2, z3; creal(z1) = 1.2; /* error */ cimag(z1) = .5; /* error */ z2 = csqrt(z1); z3 = z1 + z2; printf("sqrt = %g %gi\n", creal(z2), cimag(z2)); printf("z1+z2 = %g %gi\n", creal(z3), cimag(z3)); return 0; } C:\WINDOWS\Desktop\data>lcc cxtest.c Error cxtest.c: 10 the left hand side of the assignment can't be assigned to Error cxtest.c: 11 the left hand side of the assignment can't be assigned to 2 errors, 0 warnings The correct syntax must be: z1 = 1.2 + cimag(z1)*I; Aug 7 '07 #13

 P: n/a in comp.lang.c i read: >creal() and cimag() are functions, which therefore do not yieldlvalues. You can't assign to them. that is not a general restriction on functions, which may certainly return a modifiable lvalue. though creal and cimag do not. -- a signature Aug 8 '07 #14

 P: n/a On Aug 8, 10:35 am, those who know me have no need of my name

 P: n/a Robert Gamble said: On Aug 8, 10:35 am, those who know me have no need of my name in comp.lang.c i read: >creal() and cimag() are functions, which therefore do not yieldlvalues. You can't assign to them. that is not a general restriction on functions, which may certainlyreturn a modifiable lvalue. Can you provide such an example? #include char *foo(char *s) { printf("%s\n", s); return s; } int main(void) { char array_of_modifiable_lvalues[] = "Hello World"; *foo(array_of_modifiable_lvalues) = 'C'; puts(array_of_modifiable_lvalues); return 0; } -- Richard Heathfield Email: -www. +rjh@ Google users: "Usenet is a strange place" - dmr 29 July 1999 Aug 8 '07 #16

 P: n/a In article , Richard Heathfield >creal() and cimag() are functions, which therefore do not yieldlvalues. You can't assign to them. >>that is not a general restriction on functions, which may certainlyreturn a modifiable lvalue. >Can you provide such an example? >char *foo(char *s){ printf("%s\n", s); return s;} The value returned by foo() is a pointer to a modifiable lvalue, not a modifiable lvalue. -- Richard -- "Consideration shall be given to the need for as many as 32 characters in some alphabets" - X3.4, 1963. Aug 8 '07 #17

 P: n/a Richard Heathfield wrote: Robert Gamble said: >On Aug 8, 10:35 am, those who know me have no need of my name >in comp.lang.c i read:creal() and cimag() are functions, which therefore do not yieldlvalues. You can't assign to them.that is not a general restriction on functions, which may certainlyreturn a modifiable lvalue. Can you provide such an example? #include char *foo(char *s) { printf("%s\n", s); return s; } int main(void) { char array_of_modifiable_lvalues[] = "Hello World"; *foo(array_of_modifiable_lvalues) = 'C'; puts(array_of_modifiable_lvalues); return 0; } foo does not return a lvalue, especially a modifiable one. It returns a value ("rvalue") of type pointer to char. You can use this value to construct a lvalue, but if that is good enough to claim the function itself returns a lvalue, what's preventing foo in int foo(void) { return 0; } int main(void) { int arr[] = { 1 }; arr[foo()] = 0; return arr[0]; } from being considered as returning a lvalue? Aug 8 '07 #18

 P: n/a Richard Tobin said: In article , Richard Heathfield >>creal() and cimag() are functions, which therefore do not yieldlvalues. You can't assign to them. >>>that is not a general restriction on functions, which may certainlyreturn a modifiable lvalue. >>Can you provide such an example? >>char *foo(char *s){ printf("%s\n", s); return s;} The value returned by foo() is a pointer to a modifiable lvalue, not a modifiable lvalue. Good point. I cannot, then, see any way that a function may return a modifiable lvalue. I await education with eager delight. -- Richard Heathfield Email: -www. +rjh@ Google users: "Usenet is a strange place" - dmr 29 July 1999 Aug 8 '07 #19

 P: n/a On Aug 8, 12:24 pm, Richard Heathfield char *foo(char *s) { printf("%s\n", s); return s; } int main(void) { char array_of_modifiable_lvalues[] = "Hello World"; *foo(array_of_modifiable_lvalues) = 'C'; puts(array_of_modifiable_lvalues); return 0; } As I fully suspect you already know, foo does not return a modifiable lvalue, it returns an rvalue which when dereferenced produces an lvalue. Robert Gamble Aug 8 '07 #20

 P: n/a On Aug 8, 12:48 pm, Richard Heathfield , Richard Heathfield >creal() and cimag() are functions, which therefore do not yieldlvalues. You can't assign to them. >>that is not a general restriction on functions, which may certainlyreturn a modifiable lvalue. >Can you provide such an example? >char *foo(char *s){ printf("%s\n", s); return s;} The value returned by foo() is a pointer to a modifiable lvalue, not a modifiable lvalue. Good point. I cannot, then, see any way that a function may return a modifiable lvalue. It cannot, functions calls evaluate either to void or rvalue expressions, that was my point. Robert Gamble Aug 8 '07 #21

 P: n/a those who know me have no need of my name >creal() and cimag() are functions, which therefore do not yieldlvalues. You can't assign to them. that is not a general restriction on functions, which may certainly return a modifiable lvalue. though creal and cimag do not. I wrote the quoted text ("creal() and cimag() are functions, ..."). Please don't snip attribution lines. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Aug 8 '07 #22

 P: n/a In article <11*********************@w3g2000hsg.googlegroups.c om>, Robert Gamble Good point. I cannot, then, see any way that a function may return amodifiable lvalue. >It cannot, functions calls evaluate either to void or rvalueexpressions, that was my point. I can't see any way that you can write a function returning a modifiable lvalue (or any lvalue at all), but that doesn't mean that a standard library function couldn't be defined to return one. -- Richard -- "Consideration shall be given to the need for as many as 32 characters in some alphabets" - X3.4, 1963. Aug 8 '07 #23

 P: n/a ri*****@cogsci.ed.ac.uk (Richard Tobin) writes: In article <11*********************@w3g2000hsg.googlegroups.c om>, Robert Gamble >Good point. I cannot, then, see any way that a function may return amodifiable lvalue. >>It cannot, functions calls evaluate either to void or rvalueexpressions, that was my point. I can't see any way that you can write a function returning a modifiable lvalue (or any lvalue at all), but that doesn't mean that a standard library function couldn't be defined to return one. Except that no standard library function is defined to return an lvalue. I suppose, theoretically, that such a function could be defined in a future version of the standard, but I sincerely hope that doesn't happen (unless a mechanism is added to allow user-defined functions to return lvalues). Perhaps the OP who claimed that functions can return modifiable lvalues was thinking of C++? -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Aug 8 '07 #24

 P: n/a In article , Keith Thompson I can't see any way that you can write a function returning amodifiable lvalue (or any lvalue at all), but that doesn't mean that astandard library function couldn't be defined to return one. >Except that no standard library function is defined to return anlvalue. Right, but the example that started this was just the sort of thing the might plausibly be made to do so: creal(myvar)=8.0; One can imagine that being implemented as a macro in such a way that it *would* work, for example #define creal(x) ((x)._realpart) which would make it natural to wish for a function to be able to do the same. Of course, it would be simpler to standardise such a thing it by requiring it to be a macro, and allowing the macro to use some kind of implementation-defined magic function if it wished to (errno is an existing example, I think). -- Richard -- "Consideration shall be given to the need for as many as 32 characters in some alphabets" - X3.4, 1963. Aug 8 '07 #25

 P: n/a ri*****@cogsci.ed.ac.uk (Richard Tobin) writes: In article , Keith Thompson >I can't see any way that you can write a function returning amodifiable lvalue (or any lvalue at all), but that doesn't mean that astandard library function couldn't be defined to return one. >>Except that no standard library function is defined to return anlvalue. Right, but the example that started this was just the sort of thing the might plausibly be made to do so: creal(myvar)=8.0; One can imagine that being implemented as a macro in such a way that it *would* work, for example #define creal(x) ((x)._realpart) which would make it natural to wish for a function to be able to do the same. Of course, it would be simpler to standardise such a thing it by requiring it to be a macro, and allowing the macro to use some kind of implementation-defined magic function if it wished to (errno is an existing example, I think). Exactly. Making it a macro would make sense (and I'd argue for calling it CREAL rather than creal). Making it a "function" that behaves in a way that no user-defined function can possibly behave would be silly. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Aug 9 '07 #26

 P: n/a On Wed, 08 Aug 2007 23:38:45 +0000, Richard Tobin wrote: In article , Keith Thompson >I can't see any way that you can write a function returning amodifiable lvalue (or any lvalue at all), but that doesn't mean that astandard library function couldn't be defined to return one. >>Except that no standard library function is defined to return anlvalue. Right, but the example that started this was just the sort of thing the might plausibly be made to do so: creal(myvar)=8.0; Where will we stop? What about atan(myvar) = 1 to set myvar to tan(1)? :-) One can imagine that being implemented as a macro in such a way that it *would* work, for example #define creal(x) ((x)._realpart) which would make it natural to wish for a function to be able to do the same. That would sound great, but for consistency with the rest of the language I'd prefer setreal(z, x). Much like ferror() which doesn't return a lvalue (but, depending on how the FILE object is made, it could be very straightforward to write a macro which does), and we have to use clearerr() to set it to zero (and have no way to set it to one). Of course, it would be simpler to standardise such a thing it by requiring it to be a macro, and allowing the macro to use some kind of implementation-defined magic function if it wished to (errno is an existing example, I think). -- Richard -- Army1987 (Replace "NOSPAM" with "email") No-one ever won a game by resigning. -- S. Tartakower Aug 9 '07 #27

 P: n/a Richard Tobin wrote: In article , Keith Thompson >I can't see any way that you can write a function returning amodifiable lvalue (or any lvalue at all), but that doesn't mean that astandard library function couldn't be defined to return one. >Except that no standard library function is defined to return anlvalue. Right, but the example that started this was just the sort of thing the might plausibly be made to do so: creal(myvar)=8.0; One can imagine that being implemented as a macro in such a way that it *would* work, for example #define creal(x) ((x)._realpart) which would make it natural to wish for a function to be able to do the same. This is EXACTLY how it is implemented in lcc-win32. This makes access to the parts of a complex number VERY efficient. The correct way is it however: double _Complex z1; .... z1 = 22.0+cimag(z1)*I; // Sets the real part to 22 or z1 = creal(z1)+22*I; // Sets the imaginary part to 22 Of course, it would be simpler to standardise such a thing it by requiring it to be a macro, and allowing the macro to use some kind of implementation-defined magic function if it wished to (errno is an existing example, I think). -- Richard Aug 9 '07 #28

### This discussion thread is closed

Replies have been disabled for this discussion.