operations on complex numbers in C99

D

David Marsh

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
 
I

Ian Collins

David said:
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.
 
K

Keith Thompson

David Marsh said:
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 latest draft of the standard is
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf>.
 
C

CBFalconer

David said:
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:

<http://cbfalconer.home.att.net/download/>
 
D

David Marsh

Ian said:
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
 
J

jacob navia

David said:
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
 
J

jacob navia

David said:
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.
 
D

Duncan Muirhead

double _Complex myvar = 5.778 + 45.87*I;
(standard notation)


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;
)
 
D

David Marsh

jacob said:
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.



(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 <stdio.h>
#include <complex.h>

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
 
K

Keith Thompson

jacob navia said:
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.

and is therefore irrelevant unless you want to make your code
gratuitously non-portable.
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.
 
O

Old Wolf

and is therefore irrelevant unless you want to make your code
gratuitously non-portable.

It's useful to know this sort of thing, for when
you have to maintain someone else's code.
 
K

Keith Thompson

Old Wolf said:
It's useful to know this sort of thing, for when
you have to maintain someone else's code.

A fair point. It's pretty obvious what '5.778 + 45.87i' means, but I
suppose not everyone would recognize that it's an extension.
 
J

jacob navia

David said:
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 <stdio.h>
#include <complex.h>

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;
 
T

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 yield
lvalues. 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.
 
R

Robert Gamble

in comp.lang.c i read:


that is not a general restriction on functions, which may certainly return
a modifiable lvalue.

Can you provide such an example?

Robert Gamble
 
R

Richard Heathfield

Robert Gamble said:
Can you provide such an example?

#include <stdio.h>

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;
}
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Richard said:
Robert Gamble said:
Can you provide such an example?

#include <stdio.h>

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?
 
R

Richard Heathfield

Richard Tobin said:
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.[/QUOTE]

Good point. I cannot, then, see any way that a function may return a
modifiable lvalue. I await education with eager delight.
 
R

Robert Gamble

Robert Gamble said:
Can you provide such an example?

#include <stdio.h>

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top