math.h functions for type _Complex

L

Lane Straatman

#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
int main(void)
{
_Complex z1, z2, z3;
z1 = .4 + .7i;
z2 = pow(z1, 2);
z3 = z1 * z1;
printf("%f, %f \n", z1);
printf("%f, %f \n", z2);
printf("%f, %f \n", z3);
system("PAUSE");
return 0;
}
In this program, z2 is not equal to z3 . z3 looks correct. On my
implementation (devcpp on its maiden voyage), z2 becomes the real part
squared, and the complex part zeros out and is probably undefined.

Q1)With C99's new types, how does one use the old math functions?

Q2)Is complex or _Complex a better type defn? LS
 
A

attn.steven.kuo

#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
int main(void)
{
_Complex z1, z2, z3;
z1 = .4 + .7i;
z2 = pow(z1, 2);
z3 = z1 * z1;
printf("%f, %f \n", z1);
printf("%f, %f \n", z2);
printf("%f, %f \n", z3);
system("PAUSE");
return 0;}

In this program, z2 is not equal to z3 . z3 looks correct. On my
implementation (devcpp on its maiden voyage), z2 becomes the real part
squared, and the complex part zeros out and is probably undefined.

Q1)With C99's new types, how does one use the old math functions?


You should use math functions designed to work with complex operands.
For example, instead of pow, use cpow.
Q2)Is complex or _Complex a better type defn? LS

The former.

Try something like:

#include <stdio.h>
#include <stdlib.h>
#include <complex.h>

int main (void)
{
double complex z1, z2, z3;
z1 = .4 + .7I;
z2 = cpow(z1, 2.0);
z3 = z1 * z1;
printf("%lf %lf\n", creal(z1), cimag(z1));
printf("%lf %lf\n", creal(z2), cimag(z2));
printf("%lf %lf\n", creal(z3), cimag(z3));
return EXIT_SUCCESS;
}
 
L

Lane Straatman

You should use math functions designed to work with complex operands.
For example, instead of pow, use cpow.
Thanks for your reply. I was completely ignorant of cpow's existence.
The former.
I think so too.
Try something like:
[refines source with better type defns and output]
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include <stdbool.h>
#define N 41
#ifdef __bool_true_false_are_defined
#define N 42
#endif
int main (void)
{
double complex z1, z2, z3;
bool flag;
z1 = .4 + .7I;
z2 = cpow(z1, 2.0);
z3 = z1 * z1;
flag = false;
flag = true;
if (flag)
{
printf("%lf %lf\n", creal(z1), cimag(z1));
printf("%lf %lf\n", creal(z2), cimag(z2));
printf("%lf %lf\n", creal(z3), cimag(z3));
printf("%d\n", N);
}
system("PAUSE");
return EXIT_SUCCESS;
}
This program is of no great profoundness; I don't know of any way to get
used to new aspects of syntax without simply plodding ahead beginning with
elementary-looking stuff. It's a bit of a trick just to get the headers
included. LS
 
K

Keith Thompson

Lane Straatman said:
#include <stdio.h>
#include <stdlib.h>

You don't use anything in said:
#include <complex.h>
int main(void)
{
_Complex z1, z2, z3;

_Complex is not a type; the complex types are "float _Complex",
"double _Complex", and "long double _Complex". If your compiler
allows _Complex by itself, it may be due to a misunderstanding by its
authors; there's an incorrect example in the standard. C99 6.7.8
Example 1 is:

int i = 3.5;
complex c = 5 + 3 * I;

which is illegal. N1124 corrects this to:

int i = 3.5;
double complex c = 5 + 3 * I;
z1 = .4 + .7i;
z2 = pow(z1, 2);

You want cpow, not pow.
z3 = z1 * z1;
printf("%f, %f \n", z1);
printf("%f, %f \n", z2);
printf("%f, %f \n", z3);

A format of "%f, %f \n" requires two arguments of type double. You're
giving it a single argument of a complex type, which invokes undefined
behavior. There's are printf formats for complex numbers; you need to
print the real and complex parts separately, using the creal() and
cimag() functions.
system("PAUSE");

I get:

sh: PAUSE: command not found
return 0;
}
In this program, z2 is not equal to z3 . z3 looks correct. On my
implementation (devcpp on its maiden voyage), z2 becomes the real part
squared, and the complex part zeros out and is probably undefined.

Q1)With C99's new types, how does one use the old math functions?

Q2)Is complex or _Complex a better type defn? LS

The new keyword is spelled "_Complex" only to avoid breaking existing
code. If you #include <complex.h>", you get "complex" as a macro that
expands to "_Complex". "_Complex" is almost deliberately ugly;
there's no need to use it in user code. Just use "complex" -- or
rather "double complex".

Here's a corrected version of your program:

#include <stdio.h>
#include <complex.h>
int main(void)
{
double complex z1, z2, z3;
z1 = .4 + .7i;
z2 = cpow(z1, 2);
z3 = z1 * z1;
printf("%f, %f \n", creal(z1), cimag(z1));
printf("%f, %f \n", creal(z2), cimag(z1));
printf("%f, %f \n", creal(z3), cimag(z1));
return 0;
}
 
L

lane straatman

You don't use anything in <stdlib.h>.
There's a system call.
_Complex is not a type; the complex types are "float _Complex",
"double _Complex", and "long double _Complex".
The problem wasn't my compiler. It was the manner in which I read
item 13 off a recent screenshot. The complex type is what is left
after you subtract '_Complex' and ';' from the line in which the type
compiles.


If your compiler
allows _Complex by itself, it may be due to a misunderstanding by its
authors; there's an incorrect example in the standard. C99 6.7.8
Example 1 is:

int i = 3.5;
complex c = 5 + 3 * I;

which is illegal. N1124 corrects this to:

int i = 3.5;
double complex c = 5 + 3 * I;
I started with 3 and 5 but ended with 4 and 7. I was unaware of
cpow. Ben is right that tgmath.h would have overloaded operators that
would still let me use pow(), but the idea is that we're all going to
use the things that C99 offers, in particular, for complex
exponentiation, cpow().

You want cpow, not pow.


A format of "%f, %f \n" requires two arguments of type double. You're
giving it a single argument of a complex type, which invokes undefined
behavior. There's are printf formats for complex numbers; you need to
print the real and complex parts separately, using the creal() and
cimag() functions.


I get:

sh: PAUSE: command not found





The new keyword is spelled "_Complex" only to avoid breaking existing
code. If you #include <complex.h>", you get "complex" as a macro that
expands to "_Complex". "_Complex" is almost deliberately ugly;
there's no need to use it in user code. Just use "complex" -- or
rather "double complex".

Here's a corrected version of your program:

#include <stdio.h>
#include <complex.h>
int main(void)
{
double complex z1, z2, z3;
z1 = .4 + .7i;
z2 = cpow(z1, 2);
z3 = z1 * z1;
printf("%f, %f \n", creal(z1), cimag(z1));
printf("%f, %f \n", creal(z2), cimag(z1));
printf("%f, %f \n", creal(z3), cimag(z1));
return 0;

}
The above is basically what steven posted, beating your punch in
cyberspace, to judge from the time. The number 13 reference was to a
screenshot I made in the context of 1142.pdf that I think has
relevance now. I'm posting from google and feel like Mr. Magoo. LS
 
K

Keith Thompson

lane straatman said:
There's a system call.

You're right, my mistake. I deleted the system("PAUSE"); call from my
copy of your program, since it the PAUSE command is non-portable.
The problem wasn't my compiler. It was the manner in which I read
item 13 off a recent screenshot. The complex type is what is left
after you subtract '_Complex' and ';' from the line in which the type
compiles.

Sorry, I can't figure out what you mean here.

The declaration you posted:

_Complex z1, z2, z3;

is illegal. Some compilers (including gcc 4.1.1) accept it. I
suspect they do so because of the incorrect exapmle in the C99
standard, corrected in n1124.pdf.

Was the code you posted not the actual code you compiled?

[...]
The above is basically what steven posted, beating your punch in
cyberspace, to judge from the time. The number 13 reference was to a
screenshot I made in the context of 1142.pdf that I think has
relevance now. I'm posting from google and feel like Mr. Magoo. LS

Not having seen your screenshot, I still have no idea what "13" refers
to. Would you care to clarify?
 
K

Keith Thompson

Lane Straatman said:
http://www.billfordx.net/screendumps/n1142_shot1.htm
I think there's a complex type of long double. If there isn't, it would
shed some light on the issue at hand. LS

n1124 is a PDF document. You should be able to copy-and-paste text
from the document and post it here, rather than having to set up a web
page with a jpg image of a screenshot.

The screenshot was a copy of paragraphs 11 through 13 of section 6.2.5
of n1124.pdf:

11 There are three _complex types_, designated as float _Complex,
double _Complex, and long double _Complex. The real floating and
complex types are collectively called the _floating types_.

12 For each floating type there is a _corresponding real type_, which
is always a real floating type. For real floating types, it is the
same type. For complex types, it is the type given by deleting the
keyword _Complex from the type name.

13 Each complex type has the same representation and alignment
requirements as an array type containing exactly two elements of
the corresponding real type; the first element is equal to the real
part, and the second element to the imaginary part, of the complex
number.

The phrase "a complex type of long double" doesn't make much sense,
I'm afraid. There is a type "long double _Complex"; its
"corresponding real type" is long double. (long double itself, of
course, is not a complex type.) There is no type "_Complex", though
some compilers may allow it.

If you have a "#include <complex.h>", the type "long double _Complex"
can be referred to as "long double complex" -- and in fact that would
be the normal way to refer to it.

I fail to see how this sheds any light on the issue at hand -- perhaps
because I've completely lost track of what the issue at hand might be.
The original program you posted had several errors; I think they've
all been pointed out. Did you have any other questions, or is
everything sufficiently clear now?
 
C

CBFalconer

Keith said:
.... snip ...

n1124 is a PDF document. You should be able to copy-and-paste
text from the document and post it here, rather than having to
set up a web page with a jpg image of a screenshot.

You can make it even simpler from a text source. N869_txt.bz2 is
such a source, slightly edited for suitability for cut and paste
quoting. It's only a 212k download. Available on my page:

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

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
L

Lane Straatman

Keith Thompson said:
If you have a "#include <complex.h>", the type "long double _Complex"
can be referred to as "long double complex" -- and in fact that would
be the normal way to refer to it.

I fail to see how this sheds any light on the issue at hand -- perhaps
because I've completely lost track of what the issue at hand might be.
The original program you posted had several errors; I think they've
all been pointed out. Did you have any other questions, or is
everything sufficiently clear now?
I have a certain reverence for the integers; I'm not alone in my belief that
they came in from on high and then we figured everything else out. C at the
onset had an integer type of int. I think there's eleven integer types.
There might be a dozen. I think C99 admits of a single boolean type 'bool'.
It would be tied with any other type, as far as how new it is to C.

Are there complex types in C? If so, how many? LS
 
L

lane straatman

Keith Thompson wrote:

You can make it even simpler from a text source. N869_txt.bz2 is
such a source, slightly edited for suitability for cut and paste
quoting. It's only a 212k download. Available on my page:
I don't think filetypes of .bz2 are windows-friendly. I did just
install cygwin and would be elated if I could read this in that
environment. LS
 
L

lane straatman

n1124 is a PDF document. You should be able to copy-and-paste text
from the document and post it here, rather than having to set up a web
page with a jpg image of a screenshot. How?

The screenshot was a copy of paragraphs 11 through 13 of section 6.2.5
of n1124.pdf:

11 There are three _complex types_, designated as float _Complex,
double _Complex, and long double _Complex. The real floating and
complex types are collectively called the _floating types_.
The screenshot really is better to convey this. "Complex types" is
rendered in italics. To answer my question, there do exist complex
types. Their cardinality is three.
12 For each floating type there is a _corresponding real type_, which
is always a real floating type. For real floating types, it is the
same type. For complex types, it is the type given by deleting the
keyword _Complex from the type name.
So we were feeling all good about ourselves after number eleven. Here
at number twelve, we're talking about deleting _Complex from a type
name, and when we look to the beginning of the sentence we see "for
complex types." Can you restate it?
13 Each complex type has the same representation and alignment
requirements as an array type containing exactly two elements of
the corresponding real type; the first element is equal to the real
part, and the second element to the imaginary part, of the complex
number.
That's why my output of undefined behavior upthread was correct. It's
aligned.

Blizzard conditions here in Western Michigan. LS
 
C

CBFalconer

lane said:
I don't think filetypes of .bz2 are windows-friendly. I did just
install cygwin and would be elated if I could read this in that
environment.

1-23-02 20:02 69,632 bzip2-100-x86-win32.exe

is the installation file for 1.0.0 on Windoze. It results in a
simple command line executable. Do some googling.

The point of bz2 is that it compresses a good deal more than zip.
This is especially effective when it is compressed once and
transmitted many times.
 
K

Keith Thompson

lane straatman said:

Probably the same way you'd copy-and-paste anything else from any
other application on your OS. The details are OS-specific, and
possibly application-specific.
The screenshot really is better to convey this. "Complex types" is
rendered in italics. To answer my question, there do exist complex
types. Their cardinality is three.

Which I represented above by adding '_' characters before and after
any italic text. It's a little extra work, but since each article is
written once and read many times, it's worth it.
So we were feeling all good about ourselves after number eleven. Here
at number twelve, we're talking about deleting _Complex from a type
name, and when we look to the beginning of the sentence we see "for
complex types." Can you restate it?

For example, "double _Complex" is a complex type, and it's
"corresponding real type" is "double" (which, of course, is not a
complex type).

[snip]
 
K

Keith Thompson

lane straatman said:
I don't think filetypes of .bz2 are windows-friendly. I did just
install cygwin and would be elated if I could read this in that
environment. LS

Under Cygwin, "bunzip2 filename.bz2".
 
M

Mark McIntyre


RTFM for your favorite PDF viewer. With Acrobat Reader there's a even
button to do it, with a really counterintuitive name like "select
text" or something.... :)
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
L

Lane Straatman

Mark McIntyre said:
RTFM for your favorite PDF viewer. With Acrobat Reader there's a even
button to do it, with a really counterintuitive name like "select
text" or something.... :)
No shit:
1. Scope

1 This International Standard specifies the form and establishes the
interpretation of

programs written in the C programming language.1) It specifies

- the representation of C programs;

- the syntax and constraints of the C language;
 
L

Lane Straatman

Keith Thompson said:
For example, "double _Complex" is a complex type, and it's
"corresponding real type" is "double" (which, of course, is not a
complex type).

#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include <math.h>
int main(void)
{
long double complex z1, z3, z4, z5;
long double mod, phi, a, b, c, d;
z1 = .4 + .7I;
a = creal(z1);
b = cimag(z1);
mod = sqrt(pow(a, 2) + pow(b, 2));
phi = atan(b/a);
c = ( (sqrt(mod)) * cos( .5 * phi ) );
d = ( (sqrt(mod)) * sin( .5 * phi ) );
z4 = c + d*I;
z5 = cpow(z1, .5);
z3 = cpow(z4, 2.0);
printf("The square root of %lf %lfi\n", creal(z1), cimag(z1));
printf("is : %lf %lfi\n", creal(z4), cimag(z4));
printf("using cpow to get the root: %lf %lfi\n", creal(z5), cimag(z5));
printf("using cpow to check the square: %lf %lfi\n", creal(z3),
cimag(z3));
system("PAUSE");
return 0;
}
Have I mixed types here in a bad way? LS
 

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

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top