fmod(-2, 2) returns 0 instead of -0

fmod(-2, 2) returns 0 instead of -0

Levi Morrison的头像

My understanding is that fmod(-2, 2) should return -0, not 0. With or without -fp-model strict I get positive 0. Is this a bug, or do I need to enable some other flag?

$ icc --version
icc (ICC) 13.0.1 20121010

13 帖子 / 0 new
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项
Levi Morrison的头像

This seems ot have double-posted. Apologies.

Sergey Kostrov的头像

You're right.

...
_tprintf( _T("FMOD for FLOAT : % f\n"), ( float )fmodf( -2.0f, 2.0f ) );
_tprintf( _T("FMOD for DOUBLE: % f\n"), ( double )fmod( -2.0L, 2.0L ) );
...

[ Intel C++ compiler v12.1.3.300 & VS 2005 ]
FMOD for FLOAT : -0.000000
FMOD for DOUBLE: -0.000000

[ Microsoft C++ compiler ( VS 2005 ) ]
FMOD for FLOAT : -0.000000
FMOD for DOUBLE: -0.000000

[ Borland C++ compiler v5.5 ]
FMOD for FLOAT : -0.000000
FMOD for DOUBLE: -0.000000

[ MinGW C++ compiler v3.4.2 ] Note: Wrong results as well
FMOD for FLOAT : 0.000000
FMOD for DOUBLE: 0.000000

Sergey Kostrov的头像

>>My understanding is that fmod(-2, 2) should return -0, not 0...

Update:

- I couldn't reproduce the problem with Intel C++ compiler ( 13.0.089 / Initial Release ) on Windows 7 Professional OS ( in a 32-bit test application )

- In your example -2 and 2 are integers and these numbers are not floating-point data types

- How did you compile a fmod( -2, 2 ) statement? There are 3 overloads for fmod CRT-function for float, double and long double floating-points data types and if I don't specify a data type Intel C++ compiler doesn't compile that statement

- On Windows platforms fmod( -2.0L, 2.0L ) is called from Microsoft CRT library ( like, msvcrt.dll ) and if it has a problem ( let's assume it... ) it can't be related to Intel C++ compiler

- Could you provide a complete test case with compiler command line options, please?

- What is your platform? Linux or Windows?

- If you're on Linux what libraries did you use?

Georg Zitzlsberger (Intel)的头像

Hello,

I can reproduce the problem on 64 bit -- 32 bit is working correctly. This is only visible if compiler optimizations make use of SVML.
Hence, if you compile w/o (aggressive) optimizations and use libm.so manually, the system's implementation is used, producing correct results, e.g.:

$ icc -lm fmod.c -O0 && ./a.out
icc: warning #10315: specifying -lm before files may supercede the Intel(R) math library and affect performance
[+] fmod(2, 2): 0.000000
[+] fmod(2, -2): 0.000000
[-] fmod(-2, 2): -0.000000
[-] fmod(-2, -2): -0.000000

I've filed a defect ticket for engineering (DPD200321811) and let you know once this is fixed.

Best regards,

Georg Zitzlsberger

Sergey Kostrov的头像

Hi Georg,

>>...I can reproduce the problem on 64 bit ...

Do you mean a 64-bit Linux platform?.

>>...This is only visible if compiler optimizations make use of SVML...

What other compiler options did you use to reproduce the problem? I see that you've used just -O0 in order to get the correct result:

>>$ icc -lm fmod.c -O0 && ./a.out

Georg Zitzlsberger (Intel)的头像

Hello Sergey,

"icc"/"icpc" are the C/C++ compiler names for Linux*, "icl" for Windows*. So, yes, the problem was reproduced on a 64 bit Linux* platform.

The problem is only not visible with optimizations using SVML being turned off (as it's the case for -O0 or -O1). Higher levels induce SVML.

Best regards,

Georg Zitzlsberger

Levi Morrison的头像

Is there some way I can track this issue somehow other than checking this thread for updates?

Georg Zitzlsberger (Intel)的头像

Hello,

you can subscribe to this thread and you'll get a notification with every new reply (including the one announcing a fix).

Btw.: Notifications did not work in the past but are back again.

Best regards,

Georg Zitzlsberger

Georg Zitzlsberger (Intel)的头像

Hello,

engineering just reported that it has been fixed beginning with Intel(R) Composer XE 2013 Update 2.

Best regards,

Georg Zitzlsberger

Sergey Kostrov的头像

Thanks, Georg and I will do a quick verification. I regret that it is reported well after the Update 2 was released ( and Update 4 is about to be released... ).

Sergey Kostrov的头像

>>...engineering just reported that it has been fixed beginning with Intel(R) Composer XE 2013 Update 2...

Here are test results with Intel C++ compiler v13.1.0.149 ( Update 2 ):

*** Tests after FIX ***

[ Intel C++ compiler v13.1.0.149 ( Update 2 ) Build 20130118 32-bit & VS 2008 ]

FMOD for FLOAT : -0.000000
FMOD for DOUBLE: -0.000000

[ Intel C++ compiler v13.1.0.149 ( Update 2 ) Build 20130118 64-bit & VS 2008 ]

FMOD for FLOAT : -0.000000
FMOD for DOUBLE: 0.000000 Note: Not Fixed

[ Borland C++ compiler v5.5 ]
FMOD for FLOAT : -0.000000
FMOD for DOUBLE: -0.000000

*** Old Tests with different C++ compilers ***

[ Intel C++ compiler v12.1.3.300 & VS 2005 ]
FMOD for FLOAT : -0.000000
FMOD for DOUBLE: -0.000000

[ Microsoft C++ compiler ( VS 2005 ) ]
FMOD for FLOAT : -0.000000
FMOD for DOUBLE: -0.000000

[ Borland C++ compiler v5.5 ]
FMOD for FLOAT : -0.000000
FMOD for DOUBLE: -0.000000

[ MinGW C++ compiler v3.4.2 ] Note: Wrong results as well
FMOD for FLOAT : 0.000000
FMOD for DOUBLE: 0.000000

Sergey Kostrov的头像

Here is updated test case:

// icl.exe /MD Test.cpp

#define _UNICODE

#include "stdio.h"
#include "tchar.h"
#include "math.h"

int main( void )
{
_tprintf( _T("FMOD for FLOAT : % f\n"), ( float )fmodf( -2.0f, 2.0f ) );
_tprintf( _T("FMOD for DOUBLE: % f\n"), ( double )fmod( -2.0L, 2.0L ) );
return ( int )0;
}

登陆并发表评论。