Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7944 Discussions

HUGE_VALF and HUGE_VALL have wrong values

tydeman
Beginner
612 Views
Those two macros are supposed to be +infinity. They are not.
One is zero, the other is NaN (pseudo-infinity).
This is with icc 11.1 on Linux. I believe the problem is with
both IA-32 and Intel 64 modes.

You guys should be using test suites to check for obvious errors like these.
0 Kudos
7 Replies
Milind_Kulkarni__Int
New Contributor II
612 Views
Hello,

I am surprised how you got that result. gcc & icc (with c99 ) show consistent results.

Here is the small code
[bash]#include 
#include 

int main()
{
printf("%d %dn", isnan(HUGE_VALF), isnan(HUGE_VALL));
return 1;
}
[/bash]


output:--

0 0

similarly, using isinf(...) will give output:-- 1 1

Same with gcc.

Please let me know how you are getting NaN & zero, when I get infinity as result.

0 Kudos
tydeman
Beginner
612 Views
Here is the C program. Note, it is using the Intel headers, not gcc's headers.

#undef __PURE_SYS_C99_HEADERS__
#define __PURE_INTEL_C99_HEADERS__
#include
#include
int main(void){
union {
float f;
unsigned int ui;
} ff;
union {
double d;
unsigned long int uli;
} dd;
union {
long double ld;
unsigned short us[5];
} ldld;
ff.f = HUGE_VALF;
dd.d = HUGE_VAL;
ldld.ld = HUGE_VALL;
printf("%2i, %g, %#x\n", (int)sizeof(HUGE_VALF), ff.f, ff.ui);
printf("%2i, %g, %#lx\n", (int)sizeof(HUGE_VAL), dd.d, dd.uli);
printf("%2i, %Lg, %#hx-%#hx-%#hx-%#hx-%#hx\n", (int)sizeof(HUGE_VALL), ldld.ld,
ldld.us[4], ldld.us[3], ldld.us[2], ldld.us[1], ldld.us[0]);
ldld.ld = ldld.ld + ldld.ld;
printf("%2i, %Lg, %#hx-%#hx-%#hx-%#hx-%#hx\n", (int)sizeof(HUGE_VALL), ldld.ld,
ldld.us[4], ldld.us[3], ldld.us[2], ldld.us[1], ldld.us[0]);
return 0;
}

I was wrong on one item. HUGE_VALL is not a pseudo-infinity. It is an unnormal.

Here is the output I get with icc 11.1 in Intel64 mode on Linux Fedora Core 10 (x86_64).

8, 0, 0
8, inf, 0x7ff0000000000000
16, 0, 0x7f80-0-0-0-0
16, nan, 0xffff-0xc000-0-0-0

That output also shows another bug: printf is printing 0 for an unnormal (which is a NaN).

That output also shows that HUGE_VALF has the wrong size (and type).
Intel's has HUGE_VALF as (double *) when it should be (float *)
And, HUGE_VALL just has the wrong value in the header.
0 Kudos
Milind_Kulkarni__Int
New Contributor II
612 Views
[bash]# ifdef __INTEL_COMPILER 
# include  
# else 
# include  
# endif 
[/bash]

To use Intel math header/library, you need to include , which is also present in intel include path.

It contains the system prototypes as well as some extra functions and datatypes including Decimal floating points , complex types, and corresponding c99 features and functions that are implemented and optimized in Intel Math Library.

Just type command:-- , after including like the above.

Then, it gives correct results.

But,DO NOT include :-- these macros

#undef __PURE_SYS_C99_HEADERS__

#define __PURE_INTEL_C99_HEADERS__


That will suggest compiler to take definitions from the math.h from Intel include path, and again the result will be incorrect.

The correct Math include file is for Intel headers , and not , as per the documentation, so the experts will point out, why the Intel version of math.h is kept in include folder.

Please let me know if it helps, and for any clarification.
0 Kudos
Om_S_Intel
Employee
612 Views
It seems an issue with Intel compiler. I have submiited a report on this to Intel compiler development team.

I willinform the forum users when there is update.
0 Kudos
tydeman
Beginner
612 Views
is not a Standard C header. Therefore, it will not be used in my application.

I also use . In looking at Intel's , I see that it does:
#define __MATHIMF_H_INCLUDED
So, even if I did use , it would do nothing after I included .

Does the order of: "-lm -limf" matter to the Linux linker?
0 Kudos
tydeman
Beginner
612 Views
Intel's and have the same two problems:
HUGE_VALF has (double *) when it should be (float *)
HUGE_VALL just has the wrong value in the headers.
0 Kudos
Milind_Kulkarni__Int
New Contributor II
612 Views
According to my glancing at mathimf.h , it takes those definitions from standard math.h usr/include library .
Its better to specify -limf. Not specifying -lm would implicitly link it, so do not worry about the order.

The definition , the one having ""HUGE_VALF has (double *) when it should be (float *)"" is not being used in if we do not use __PURE_INTEL_C99_HEADERS__ ..

If you go through the definitions of HUGE_VALF & HUGE_VALL in Intel & , there is small difference in the #if defined macro checking. In Intel math.h, you also check for defined (__PURE_INTEL_C99_HEADERS__) . while in , you do not check for it.

Though this should be considered a bug in itself, because the use of __PURE_INTEL_C99_HEADERS__ alters the size & definition of those HUGE types, and it should not happen, as it interferes with definition provided by Gcc headers.

Lastly, after the fix , it should work consistently with or without INTEL_C99_HEADERS , and I think it would not then matter whether you use Intel math.h or mathimf.h .

According to the documentation, mathimf is for a mathematical software library containing highly optimized and very accurate and speedy mathematical functions, which should have a performance benefit to use over standard math library.
0 Kudos
Reply