How to pass infinity values to a function and test the result - c

I have this function:
#include <complex.h>
complex double f(complex double x, complex double y) {
return x*y;
}
I would like to call it with x = inf + i inf and y = i inf and see what the result is. In particular I want to test if the result is an infinity value (as it should be) or if it is NaN + iNaN. The reason for this is to test different C compilers.
How do you do this in C?

I would add an intermediate check, too:
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include <math.h>
complex double f(complex double x, complex double y) {
return x*y;
}
int main(void){
complex double x = INFINITY + INFINITY * I;
complex double y = 0.0 + INFINITY * I;
complex double ret;
printf("x = %g + %g*I\n", creal(x), cimag(x));
printf("y = %g + %g*I\n", creal(y), cimag(y));
ret = f(x,y);
printf("f = %g + %g*I\n", creal(ret), cimag(ret));
exit(EXIT_SUCCESS);
}
Why?
Result with gcc-4.9.real (Ubuntu 4.9.4-2ubuntu1~14.04.1) 4.9.4
x = nan + inf*I
y = nan + inf*I
f = -inf + -nan*I
Result with Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
x = nan + inf*I
y = nan + inf*I
f = nan + nan*I
A complete and utter failure from the get go.

I'm not 100% sure this is correct since I've never worked with complex numbers in C, but I've tried this snippet:
#include <stdio.h>
#include <math.h>
#include <complex.h>
double complex f(double complex x, double complex y) {
return x*y;
}
int main(void)
{
double complex z1 = INFINITY + INFINITY * I;
double complex z2 = INFINITY + INFINITY * I;
complex double result = f(z1, z2);
printf("%f + i%f\n", creal(result), cimag(result));
}
I used both clang 3.8 (C 11) and GCC 6.1 (C 11) and the result was:
-inf + i-nan
Based on http://en.cppreference.com/w/c/numeric/math/INFINITY.
Apparently the macro INFINITY is not always supported and thus defined. Check the link above for more info.

You can specify what is basically a complex literal using multiplication with the I macro (which also has a _Complex_I alias). A minor example creating such a value is seen below:
#include <math.h>
#include <complex.h>
int main()
{
complex c = INFINITY * I + INFINITY;
}

The function, as written, is fine, the problem is with the way the complex numbers with special values are created and interpreted.
If you just write
double complex z1 = I * INFINITY;
double complex z2 = INFINITY + I * INFINITY;
you may discover that most of the popular compilers today do not support C99's imaginary numbers, and this expression actually multiplies (0,1) by (inf,0) and then adds (inf,0) to the result.
With gcc, I get z1 = (nan, inf), z2 = (nan, inf), f(z1,z2) = (-inf, -nan)
with clang, I get z1 = (nan, inf), z2 = (nan, inf), f(z1,z2) = (-inf, -nan)
with icc, I get z1 = (-nan, inf), z2 = (-nan, inf), f(z1, z2) = (-nan, -nan)
The only compiler that defines I as a pure imaginary number that I have access to is the C compiler from Oracle Studio
with oracle studio, I get z1 = (0, inf), z2 = (inf, inf), f(z1,z2) = (-inf, inf)
Now this is not actually supposed to be a problem because in C, there is only one Complex Infinity, and every complex number whose one component is infinite is considered to be that infinity, even if the other component is NaN. All built-in arithmetic is supposed to honor that: so in my list above, only Intel appears to have a bug here where multiplication of two complex infinities gave a complex nan.
For the lazy compilers, C11 has a macro that saves the day: CMPLX
double complex z1 = CMPLX(0, INFINITY);
double complex z2 = CMPLX(INFINITY, INFINITY);
now,
with gcc, I get z1 = (0, inf), z2 = (inf, inf), f(z1,z2) = (-inf, inf)

Related

-2.6 to the power of 0.2 outputs #IND00

currently i'm doing my practice for C language and i've found one question about function pow() in C\C++.
#include <stdio.h>
#include <math.h>
int main(){
double k = 0.2;
printf("2.6^k = %f\n", pow(2.6, k));
printf("-2.6^k = %f\n", pow(-2.6, k));
}
OUTPUT:
2.6^k = 1.210583
-2.6^k = -1.#IND00
In this example -2.6 to the power of 0.2 i̶s̶ ̶n̶o̶t̶ ̶e̶v̶e̶n̶ ̶a̶ ̶c̶o̶m̶p̶l̶e̶x̶ ̶n̶u̶m̶b̶e̶r̶(Edit: it is),but output says(as i think) that number is indeterminable.
And in my practice there is the following:
image
I implemented this like that:
/* e = 2.1783; x = -2.6 */
result = pow(cos(pow(x,0.2) - pow(e,-x + sqrt(3))) + 1.61,2);
But due to (-x + sqrt(3)) being negative number it outputs:
-1.#IND00
The value 0.2 cannot be represented exactly in binary floating point. So what you have is not actually 0.2 but a value slightly more than that. This yields a complex result so pow returns NaN.
Reading into this further, section 7.12.7.4 of the C standard regarding the pow function states:
double pow(double x, double y);
A domain error occurs if x is finite
and negative and y is finite and not an integer value.
In the event of a domain error, an implementation-defined value is returned. While MSVC doesn't seem to document what it does in this case, it apparently returns NaN. In the case of Linux, the man pages explicitly state that NaN is returned in this case.
With complex number math, -2.60.2 is 0.979382 +0.711563*i.
pow(-2.6, k) does not have a real answer.
Alternative: use complex math:
#include <complex.h>
#include <math.h>
#include <stdio.h>
int main(void) {
double k = 0.2;
printf("2.6^k = %f\n", pow(2.6, k));
complex double y = cpow(-2.6, k);
printf("-2.6^k = %f %f*i\n", creal(y), cimag(y));
}
Output
2.6^k = 1.210583
-2.6^k = 0.979382 0.711563*i

wrong calculation when using float

I'm trying to do a calculation and for some reason when I'm using float I'm getting -nan(ind) but when I'm changing the variables (x,y) to double I'm getting to right answer maybe you guys have any idea why its happening ?
Thank you
#include <stdio.h>
#include <math.h>
#define pi 3.1416
#define L1 0.5
#define L2 0.5
void main()
{
float q1[12], q2[12], q1_Degrees[12], q2_Degrees[12];
float x = 0.8;
float y = 0.6;
q2[0] = acos((pow(x, 2) + pow(y, 2) - pow(L1, 2) - pow(L2, 2)) / (2 * L1*L2));
q1[0] = atan(y / x) - atan((L2*sin(q2[0])) / (L1 + L2 * cos(q2[0])));
q1_Degrees[0] = (q1[0] * 180) / pi;
q2_Degrees[0] = (q2[0] * 180) / pi;
printf_s("q1 is = %.1f q2 is = %.1f\n\n", q1_Degrees[0], q2_Degrees[0]);
}
2 concerns
acos()
The x in acos(x) needs to be in the range [-1...1]. Outside that, the result may be NaN.
(pow(x, 2) + pow(y, 2) - pow(L1, 2) - pow(L2, 2)) / (2 * L1*L2) is prone to slight effects of computation that result in a value just outside [-1...1] even if mathematically the result should be in range.
A quick work-around:
double z = (pow(x, 2) + pow(y, 2) - pow(L1, 2) - pow(L2, 2)) / (2 * L1*L2);
if (z < -1.0) z = -1.0;
else if (z > 1.0) z = 1.0;
q2[0] = acos(z);
The issue applies to double, float, long double. The fact it "worked" with one type is no reason to believe code is robust with other values.
Note that code is calling double functions like acos(), pow() and not their float counterparts acosf(), powf(). I recommend to use double throughout unless you have a compelling reason otherwise.
atan
atan() provides a [-π/2... +π/2] radians (aka [-90...90] degrees) result.
A whole circle result of [-π... +π] radians (aka [-180...180] degrees) is available with atan2(y,x)
atan((L2*sin(q2[0])) / (L1 + L2 * cos(q2[0])))
// or
atan2(L2*sin(q2[0]), L1 + L2 * cos(q2[0]))
A better solution is to use a different form of trig manipulation that does not depend on the edge of acos(). Easiest to do if OP also posted the higher level goal of the exercise.
Some basic debugging:
First, you can narrow down your code to:
#include <stdio.h>
#include <math.h>
void main()
{
float x = 0.8;
float y = 0.6;
double q = acos((pow(x, 2) + pow(y, 2) - 0.5) * 2);
printf("q = %lf\n", q);
}
Then, it becomes obvious that either pow(x, 2) or pow(y, 2) yield slightly different results for float and double.
At this point, let's investigate the actual differences:
Between the value of (float)0.8 and the value of (double)0.8
Between the value of (float)0.6 and the value of (double)0.6
#include <stdio.h>
void main()
{
printf("(float)0.8 = %.10f\n", (float)0.8);
printf("(double)0.8 = %.10lf\n", (double)0.8);
printf("(float)0.6 = %.10f\n", (float)0.6);
printf("(double)0.6 = %.10lf\n", (double)0.6);
}
The printout is:
(float)0.8 = 0.8000000119
(double)0.8 = 0.8000000000
(float)0.6 = 0.6000000238
(double)0.6 = 0.6000000000
Does that answer your question?
You're getting accumulated roundoff which runs a bit past the domain of acos().
Simplifying your example to a minimum that shows the issue:
#include <stdio.h>
#include <math.h>
#define L1 0.5
#define L2 0.5
int main()
{
float x = 0.8;
float y = 0.6;
float acos_param = (pow(x, 2) + pow(y, 2) - pow(L1, 2) - pow(L2, 2)) / (2 * L1*L2);
float q2 = acos(acos_param);
printf("acos_param = %.9f; q2 = %.9f\n", acos_param, q2);
return 0;
}
And running this - with floats - we see:
acos_param = 1.000000119; q2 = nan
Aha: greater than 1.0 is out of range of acos so you get NaN (not a number).
Changing all the float to double we get:
acos_param = 1.000000000; q2 = 0.000000000
which is more in line with expectations.
EDIT - Expanding on comments in the comments, variadic functions in C always pass floating-point values as double, and the misleadingly-named format %f really means double, not float.
Even if you attempt to cast "down" to a float, it will get promoted again back to double before it's called, but will truncate the precision.
Try this:
#include <stdio.h>
int main()
{
double d1 = 0.8;
double d2 = (float)0.8;
printf("d1=%.9f; d2=%.9f\n", d1, d2);
return 0;
}
Which on my compiler produces:
d1=0.800000000; d2=0.800000012
Here, d1 is the full real-deal double, while d2 is the float-truncated version promoted back to double.
And in no case is the l format specifier need; %f and %lf are the same thing.

How to compute a cubic root of a complex number in C?

As the name suggested, I'd like to compute cubic roots of a complex number in C. cbrt doesn't work.
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include <cmath.h>
int main(){
double complex x, z = 1+2*I;
x = cbrt(z);
printf("z is %f + %fi \n", creal(z), cimag(z));
printf("x is %f + %fi \n", creal(x), cimag(x));
return(0);
}
The output is as follows.
z is 1.000000 + 2.000000i
x is 1.000000 + 0.000000i
cbrt doesn't work.
That function works on real values. #squeamish ossifrage
x is 1.000000 + 0.000000i is a reasonable result.
double cbrt(double x);
The cbrt functions compute the real cube root of x. C11dr §7.12.7.1 2
A good compiler with warnings fully enabled with report on the following. Save time, enable all compiler warnings.
// warning expected such as:
// warning: conversion to 'long double' from 'complex double' discards imaginary component [-Wconversion]
x = cbrt(z);
How to compute a cubic root of a complex number in C?
<cmath.h> is not part of the C standard library. Its role here is unclear.
Code can use double complex cpow(double complex, double complex);
x = cpow(z, 1.0/3.0);
...
// Ouptut
// x is 1.219617 + 0.471711i
I do not find a double complex ccbrt(double complex); in the standard library nor access to one via type-generic math <tgmath.h>.
... to compute cubic roots ...
Emphasis on plural "roots" here: to compute all 'n' roots:
int n = 3;
const double complex two_pi_i = 2.0 * asin(-1.0) * I;
double complex rotate = cexp(two_pi_i / n);
x = cpow(z, 1.0 / 3.0);
for (int k = 0; k < n; k++) {
printf("x[%d] is % f + % fi \n", k, creal(x), cimag(x));
x *= rotate;
}
Output
x[0] is 1.219617 + 0.471711i
x[1] is 1.018322 + -0.820363i
x[2] is -0.201294 + -1.292075i
I would look at this answer from the Mathematics Stack Exchange.
Essentially you want to compute the radius and angle of the Eurler formula. Then divide both the radius and angle by three (see link). So first you need to convert your complex number to Euler format. I don't have time now to figure that out, but maybe this gave you an idea at where to look.
Hope this helps!
Addition: #squeamish probably has a better idea with cpow, but as he mentioned this will only return one of the roots.

How to create a complex type of a existing function?

I am just beginning C programming (not C++) and I have to convert the quadratic formula for adressing complex roots, and for printing these. The normal quadratic equation is as follows (for discriminant > 0):
else {
/* */
x1 = ((-b) + sqrt(discr)) / (2 * a);
x2 = ((-b) - sqrt(discr)) / (2 * a);
printf("%s%.4lf%s%.4lf\n\n", "x1: ", x1, "\tx2: ", x2);
}
When I try to convert this into its complex values I have used the following strategies:
Creating a new version of the result of the sqrt(discr), the complex part in the equation, by creating a variable _Complex double discr_complex = discr * I.
-> OR discr_complex = discr + discr * I.
Making x1 and x2 complex by 'complex x1' or '_Complex c1' or 'complex x1 = ..formula.. * I' or '_Complex x1 = ...formula * I'.
Making every part complex by using the keyword complex.
For all these versions it does not print the correct complex output (#+#i). I tried printing the normal values, which works, but not for the complex part. I tried using the methods creal(x1) and cimag(x1) which do not work (undeclared reference to creal / cimag), or x1.real() / x1.imag(), which also doesn't work ('imag' in something not a structure or union).
Does anybody maybe know how to convert my x1 and x2 values into complex numbers, with maybe a clear explanation how to return each seperate part of the complex equation (real/imaginary) and how this conversion takes place taken my 'normal' formula?
The reason that calling creal does not work is that either you have not included the proper header complex.h or you are calling it with an argument x1 that is not of the correct type double complex. The second error, when you call x1.real() is because the . notation tries to access a member of a struct but x1 is a double.
I suggest using complex.h that enables working with complex numbers and define a new abc-formula that deals with complex numbers. Also note that you can not use 'regular' math functions like sqrt on variables of complex type but need to use the complex.h analogs e.g. csqrt()
#include <complex.h>
int main(void)
{
double complex z = 1.0 + 0.5 * I;
printf("The real part of z = %f\n", creal(z));
printf("The iamginary part of z = %f\n", cimag(z));
return 0;
}
Edit:
completely redefine your function, try something like this:
void complex_abc() {
double complex a = 1;
double complex b = 2;
double complex c = 3;
double complex x1;
double complex x2;
double complex d;
d = b*b - 4 * a * c;
x1 = ( -b + csqrt(d) ) / 2*a;
x2 = ( -b - csqrt(d) ) / 2*a;
printf("x1 = %f + i %f\n", creal(x1), cimag(x1));
printf("x2 = %f + i %f\n", creal(x2), cimag(x2));
return;
}
And as correctly noted by #Lutzl in the comments you need to link the math library with the flag -lm during compiling

How to work with complex numbers in C?

How can I work with complex numbers in C? I see there is a complex.h header file, but it doesn't give me much information about how to use it. How to access real and imaginary parts in an efficient way? Is there native functions to get module and phase?
This code will help you, and it's fairly self-explanatory:
#include <stdio.h> /* Standard Library of Input and Output */
#include <complex.h> /* Standard Library of Complex Numbers */
int main() {
double complex z1 = 1.0 + 3.0 * I;
double complex z2 = 1.0 - 4.0 * I;
printf("Working with complex numbers:\n\v");
printf("Starting values: Z1 = %.2f + %.2fi\tZ2 = %.2f %+.2fi\n", creal(z1), cimag(z1), creal(z2), cimag(z2));
double complex sum = z1 + z2;
printf("The sum: Z1 + Z2 = %.2f %+.2fi\n", creal(sum), cimag(sum));
double complex difference = z1 - z2;
printf("The difference: Z1 - Z2 = %.2f %+.2fi\n", creal(difference), cimag(difference));
double complex product = z1 * z2;
printf("The product: Z1 x Z2 = %.2f %+.2fi\n", creal(product), cimag(product));
double complex quotient = z1 / z2;
printf("The quotient: Z1 / Z2 = %.2f %+.2fi\n", creal(quotient), cimag(quotient));
double complex conjugate = conj(z1);
printf("The conjugate of Z1 = %.2f %+.2fi\n", creal(conjugate), cimag(conjugate));
return 0;
}
with:
creal(z1): get the real part (for float crealf(z1), for long double creall(z1))
cimag(z1): get the imaginary part (for float cimagf(z1), for long double cimagl(z1))
Another important point to remember when working with complex numbers is that functions like cos(), exp() and sqrt() must be replaced with their complex forms, e.g. ccos(), cexp(), csqrt().
Complex types are in the C language since C99 standard (-std=c99 option of GCC). Some compilers may implement complex types even in more earlier modes, but this is non-standard and non-portable extension (e.g. IBM XL, GCC, may be intel,... ).
You can start from http://en.wikipedia.org/wiki/Complex.h - it gives a description of functions from complex.h
This manual http://pubs.opengroup.org/onlinepubs/009604499/basedefs/complex.h.html also gives some info about macros.
To declare a complex variable, use
double _Complex a; // use c* functions without suffix
or
float _Complex b; // use c*f functions - with f suffix
long double _Complex c; // use c*l functions - with l suffix
To give a value into complex, use _Complex_I macro from complex.h:
float _Complex d = 2.0f + 2.0f*_Complex_I;
(actually there can be some problems here with (0,-0i) numbers and NaNs in single half of complex)
Module is cabs(a)/cabsl(c)/cabsf(b); Real part is creal(a), Imaginary is cimag(a). carg(a) is for complex argument.
To directly access (read/write) real an imag part you may use this unportable GCC-extension:
__real__ a = 1.4;
__imag__ a = 2.0;
float b = __real__ a;
For convenience, one may include tgmath.h library for the type generate macros. It creates the same function name as the double version for all type of variable. For example, For example, it defines a sqrt() macro that expands to the sqrtf() , sqrt() , or sqrtl() function, depending on the type of argument provided.
So one don't need to remember the corresponding function name for different type of variables!
#include <stdio.h>
#include <tgmath.h>//for the type generate macros.
#include <complex.h>//for easier declare complex variables and complex unit I
int main(void)
{
double complex z1=1./4.*M_PI+1./4.*M_PI*I;//M_PI is just pi=3.1415...
double complex z2, z3, z4, z5;
z2=exp(z1);
z3=sin(z1);
z4=sqrt(z1);
z5=log(z1);
printf("exp(z1)=%lf + %lf I\n", creal(z2),cimag(z2));
printf("sin(z1)=%lf + %lf I\n", creal(z3),cimag(z3));
printf("sqrt(z1)=%lf + %lf I\n", creal(z4),cimag(z4));
printf("log(z1)=%lf + %lf I\n", creal(z5),cimag(z5));
return 0;
}
The notion of complex numbers was introduced in mathematics, from the need of calculating negative quadratic roots. Complex number concept was taken by a variety of engineering fields.
Today that complex numbers are widely used in advanced engineering domains such as physics, electronics, mechanics, astronomy, etc...
Real and imaginary part, of a negative square root example:
#include <stdio.h>
#include <complex.h>
int main()
{
int negNum;
printf("Calculate negative square roots:\n"
"Enter negative number:");
scanf("%d", &negNum);
double complex negSqrt = csqrt(negNum);
double pReal = creal(negSqrt);
double pImag = cimag(negSqrt);
printf("\nReal part %f, imaginary part %f"
", for negative square root.(%d)",
pReal, pImag, negNum);
return 0;
}
To extract the real part of a complex-valued expression z, use the notation as __real__ z.
Similarly, use __imag__ attribute on the z to extract the imaginary part.
For example;
__complex__ float z;
float r;
float i;
r = __real__ z;
i = __imag__ z;
r is the real part of the complex number "z"
i is the imaginary part of the complex number "z"

Resources