Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- Intel Community
- Software
- Software Development Tools (Compilers, Debuggers, Profilers & Analyzers)
- Intel® C++ Compiler
- Complex multiplication in C Compiler 17 appears not to be C99 compliant

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

Raphael_C_

Beginner

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-06-2017
01:47 AM

222 Views

Complex multiplication in C Compiler 17 appears not to be C99 compliant

This code:

#include <complex.h>

complex double f(complex double x, complex double y) {

return x*y;

}

when compiled with -O3 -march=core-avx2 -fp-model strict using Intel Compiler version 17 gives

f:

vunpcklpd xmm5, xmm0, xmm1

vmovddup xmm4, xmm2

vmovddup xmm6, xmm3

vshufpd xmm7, xmm5, xmm5, 1

vmulpd xmm8, xmm4, xmm5

vmulpd xmm9, xmm6, xmm7

vaddsubpd xmm0, xmm8, xmm9

vunpckhpd xmm1, xmm0, xmm0

ret

According to Annex G, Section 5.1, Paragraph 4 of the specs:

if **x** = a * *i*b is infinite and **y** = c * *i*d is infinite, the number **x** * **y** must be infinite.

But if we let **x** = inf + i inf (an infinite value) and y = i inf (an infinite value) the result for the Intel code is **x** * **y** = NaN + *i*NaN due to the inf times 0 intermediates. This does not conform to the C99 specs as far as I can see.

Is this a bug and/or is there another set of flags to make complex multiplication C99 compliant?

Link Copied

23 Replies

Yuan_C_Intel

Employee

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-08-2017
06:51 AM

205 Views

Hi, Raphael

Please try add option -std=c99 to align with C99 standard. By default the C compiler conforms to ISO C90 plus GNU extension on Linux.

Hope this helps.

Thanks.

Raphael_C_

Beginner

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-08-2017
06:53 AM

205 Views

Adding -std=c99 does not change the assembly code at all.

Raphael_C_

Beginner

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-08-2017
08:02 AM

205 Views

Here is full code to reproduce the problem:

```
#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 * I;
complex double result = f(z1, z2);
printf("%f + i%f\n", creal(result), cimag(result));
}
```

With icc -std=c99 -Wall test-inf.c -o test-inf-icc you get

-nan + i-nan

which is not correct.

Raphael_C_

Beginner

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-08-2017
10:00 AM

205 Views

I meant

icc -std=c99 -fp-model strict test-inf.c -o test-inf-icc

which still gives the same incorrect output.

Raphael

Yuan_C_Intel

Employee

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-08-2017
08:23 PM

205 Views

Hi, Raphael

Thank you for the small reproducer.

I can reproduce the issue you reported. There are two warnings which shows INFINITY*I is treated as an out of range number for complex type. This should be incorrect.

I have escalated this issue and entered it in our problem tracking system. I will let you know when I have an update on this issue.

Thank you.

Raphael_C_

Beginner

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
09:40 AM

205 Views

Thank you very much. I look forward to hearing about any updates.

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
12:04 PM

205 Views

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
12:04 PM

205 Views

I don't want to put all my comments in one big post and take a look at my next posts.

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
12:09 PM

205 Views

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
12:14 PM

205 Views

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
12:16 PM

205 Views

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
12:19 PM

205 Views

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
12:22 PM

205 Views

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
12:24 PM

205 Views

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
12:40 PM

205 Views

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
12:53 PM

205 Views

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-09-2017
01:01 PM

205 Views

Raphael_C_

Beginner

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-10-2017
02:30 AM

205 Views

Thanks for all this Sergey Kostrov. An answer and a comment.

> The function **f** is declared as **double complex f( double complex x, double complex y )** but a **result** variable is declared as **complex double** instead of **double complex**. Is that an error in your test case?

Quoting from http://stackoverflow.com/a/41679314/2179021 ,

"`complex`

is a macro from complex.h which expands into the type specifier `_Complex`

. This behaves as all other type specifiers, for example `int, bool, double`

. For all type specifiers belonging to the same "group", you can combine them in various orders. This is specified by C11 6.7.2[...]"

In other words, **double complex** and **complex double** are equivalent.

In relation yto our other comments about the behaviour of different C compilers, you might also be interested in the output of this code:

```
#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);
}
```

`In both gcc 5.4.0 and clang 3.8 you get:`

x = nan + inf*I

y = nan + inf*I

f = -inf + -nan*I

icc outputs:

x = -nan + inf*I

y = -nan + inf*I

f = -nan + -nan*I

The output " f = -inf + -nan*I" that gcc and clang give is arguably strictly speaking correct as C99 defines any complex value with a part that is inf to be an infinity.

http://stackoverflow.com/a/42122851/2179021 shows what you have to do if you want to get x = inf + inf*I in gcc/clang/icc. That post also finishes with:

"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."

Note that my query is 100% about C and not C++.

SergeyKostrov

Valued Contributor II

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-10-2017
09:16 AM

205 Views

Melanie_B_Intel

Employee

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-10-2017
11:55 AM

41 Views

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

For more complete information about compiler optimizations, see our Optimization Notice.