- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am surprised how you got that result. gcc & icc (with c99 ) show consistent results.
Here is the small code
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.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
#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
And, HUGE_VALL just has the wrong value in the header.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[bash]# ifdef __INTEL_COMPILER # include# else # include # endif [/bash]
To use Intel math header/library, you need to include
It contains the system
Just type command:--
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
Please let me know if it helps, and for any clarification.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
I willinform the forum users when there is update.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I also use
#define __MATHIMF_H_INCLUDED
So, even if I did use
Does the order of: "-lm -limf" matter to the Linux linker?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
HUGE_VALF has (double *) when it should be (float *)
HUGE_VALL just has the wrong value in the headers.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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 you go through the definitions of HUGE_VALF & HUGE_VALL in Intel
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.
Reply
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