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

Differences in tangent function between ifort and icc

HenriqueRenno
Beginner
1,965 Views

As already mentioned in another post, I'm working with a scientific model and translating it from Fortran 90 to C.

 

The original Fortran code uses the tand() function, which computes the tangent of an angle given in degrees. As there is no similar function in C, the argument must be converted from degrees to radians for the tan() function.

 

Maybe due to this conversion, the results from the two functions between the languages are not the same, and a further computation that uses the tangent value becomes different as expected.

 

However, I noticed that, in some cases, the final results are the same, even though the tangent functions return different values. For example:

 

Fortran

Case 1:

angle = -7.10521984100341796875

tand = 0.124649100005626678466796875

result = 15.75165843963623046875

Case 2:

angle = -10.8127498626708984375

tand = 0.1909908354282379150390625

result = 16.2542781829833984375

 

C

Case 1:

angle = -7.10521984100341796875

tan = 0.1246490776538848876953125 (different)

result = 15.75165843963623046875 (same)

Case 2:

angle = -10.8127498626708984375

tan = 0.19099080562591552734375 (different)

result = 16.25428009033203125 (different)

 

All computations are performed with single-precision floating-point variables, as in the original Fortran code.

 

My doubt is which changes I could make in the code so that the C version produces the same results as the Fortran version.

 

Please, find attached two sample codes that reproduce the problem (tanC.c and tanF.f90). The compiler versions and compilation instructions are given as below.

 

Compilers (ifort and icc are stand-alone versions):

- ifort -v: ifort version 2021.6.0

- icc -v: icc version 2021.7.1 (gcc version 8.3.1 compatibility)

- gcc -v: gcc version 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC)

 

Compilation:

- ifort: ifort -o tanIFORT.x tanF.f90

- icc: icc -fp-model=precise -o tanICC.x tanC.c

 

Thanks for your help

0 Kudos
1 Solution
SeshaP_Intel
Moderator
1,296 Views

Hi,

 

To minimize output differences, you need to maintain the same computation (including the same floating-point format, and the same function calls). 

The sind/cosd/tand functions are available in the Intel Math library function list. Please refer to the below link for more details.

https://www.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/optimization-and-programming/intel-c-compiler-classic-math-library/trigonometric-functions.html

And their prototypes are declared in mathimf.h, For e.g.:

 

extern double cosd( double __x );
extern float cosdf( float __x );

extern double sind( double __x );
extern float sindf( float __x );

extern double tand( double __x );
extern float tandf( float __x );

Could you please try this on your end and let us know the results?

 

Thanks and Regards,

Pendyala Sesha Srinivas

 

View solution in original post

0 Kudos
11 Replies
SeshaP_Intel
Moderator
1,898 Views

Hi,


Thank you for posting in Intel Communities.

We were able to reproduce your issue. We are working on this internally.

We will get back to you soon.


Thanks and Regards,

Pendyala Sesha Srinivas


0 Kudos
SeshaP_Intel
Moderator
1,848 Views

Hi,

 

To get the same result for both compilers, the same type of conversion(degree to radian) should be used in both files.

You can compare the results of tanC.c with mod_tanF.f90 and mod_tanC.c with tanF.f90.

Please find the below screenshots for the results.

mod_icc.png

mod_IFORT.png

Please find the zip file which contains the modified source files.

 

Thanks and Regards,

Pendyala Sesha Srinivas

 

0 Kudos
HenriqueRenno
Beginner
1,806 Views

Hello,

 

Thanks for your reply. By changing the code with these modifications, most of the results now match, but I just found some cases where the results still differ.

 

Now the problem seems to be with the cos() function (Case 3). In addition, the sin() function also returned different results in the previous cases (Cases 1 and 2), but the final results matched. Here is the output:

 

Fortran

Case 1:

angle = -7.10521984100341796875

tand = 0.124649100005626678466796875

sind = -0.123691879212856292724609375

cosd = 0.99232065677642822265625

result = 15.75165843963623046875

Case 2:

angle = -10.8127498626708984375

tand = 0.1909908354282379150390625

sind = -0.1875998973846435546875

cosd = 0.982245504856109619140625

result = 16.2542781829833984375

Case 3:

angle = -7.234119892120361328125

tand = 0.1269344389438629150390625

sind = -0.1259240210056304931640625

cosd = 0.992039859294891357421875

result = 15.770061492919921875

 

C

Case 1:

angle = -7.10521984100341796875

tan = 0.124649100005626678466796875 (equal)

sin = -0.1236918866634368896484375 (different)

cos = 0.99232065677642822265625 (equal)

result = 15.75165843963623046875 (equal)

Case 2:

angle = -10.8127498626708984375

tan = 0.1909908354282379150390625 (equal)

sin = -0.18759988248348236083984375 (different)

cos = 0.982245504856109619140625 (equal)

result = 16.2542781829833984375 (equal)

Case 3:

angle = -7.234119892120361328125

tan = 0.1269344389438629150390625 (equal)

sin = -0.1259240210056304931640625 (equal)

cos = 0.9920399188995361328125 (different)

result = 15.7700634002685546875 (different)

 

Do you know how the tand(), sind(), and cosd() Fortran functions convert the angle from degree to radians? I tried different conversions, but the differences still persist.

 

Maybe if the same conversion that is performed by the Fortran functions could be added to the C version, these differences would not occur anymore. Is it possible to check how those Fortran functions convert the input angle?

 

I have attached the updated codes for testing.

 

Again, thanks for your help.

0 Kudos
HenriqueRenno
Beginner
1,749 Views

Hello,

 

Do you have any news about the other doubts?

 

Thanks

0 Kudos
SeshaP_Intel
Moderator
1,723 Views

Hi,

 

Please check the modified source file(file.c ). We have checked with different values of input and compared the results.

We are able to get the same results. Hope this helps to resolve your issue.

 

Thanks and Regards,

Pendyala Sesha Srinivas

 

0 Kudos
HenriqueRenno
Beginner
1,692 Views

Hello,

 

This new modified source file contains the same type of conversion that you mentioned in a previous post. This modification does not work in all cases as I pointed out before. I tested this new code and the results from the sin() and cos() C functions do not match the results from sind() and cosd() Fortran functions, which in some cases give different results for the final computation between the two languages.

 

I believe that the sind(), cosd(), and tand() Fortran functions perform another type of conversion besides the one you provided. Do you know if the source code of the sind(), cosd(), and tand() Fortran functions are available, so that one could see how they internally perform the conversion from degrees to radians?

 

Please, let me know if you have any new information about this issue?

 

Thanks for your help.

0 Kudos
HenriqueRenno
Beginner
1,639 Views

Hello,

 

I'm attaching updated codes with modifications that also print the binary values of the results computed by the tan(), sin(), and cos() C functions, as well as the tand(), sind(), and cosd() Fortran functions.

 

When you execute the C and Fortran codes, you will see that the results differ in the last bits, possibly due to some rounding related to the conversion that is performed by the Fortran functions.

 

Is there no way for the results to match?

 

Thanks

0 Kudos
SeshaP_Intel
Moderator
1,334 Views

Hi,


We are working on your issue. We will get back to you soon.


Thanks and Regards,

Pendyala Sesha Srinivas


0 Kudos
HenriqueRenno
Beginner
1,314 Views

Hello,

 

I made use of the interoperability between Fortran and C, so I compiled one Fortran code including the sind(), cosd(), and tand() functions, and then linked them as external functions to be called by the C code. This solution worked, but it's not a full C solution.

 

I'll wait for your reply, so maybe I could avoid mixing Fortran and C codes.

 

Thanks

0 Kudos
SeshaP_Intel
Moderator
1,297 Views

Hi,

 

To minimize output differences, you need to maintain the same computation (including the same floating-point format, and the same function calls). 

The sind/cosd/tand functions are available in the Intel Math library function list. Please refer to the below link for more details.

https://www.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/optimization-and-programming/intel-c-compiler-classic-math-library/trigonometric-functions.html

And their prototypes are declared in mathimf.h, For e.g.:

 

extern double cosd( double __x );
extern float cosdf( float __x );

extern double sind( double __x );
extern float sindf( float __x );

extern double tand( double __x );
extern float tandf( float __x );

Could you please try this on your end and let us know the results?

 

Thanks and Regards,

Pendyala Sesha Srinivas

 

0 Kudos
SeshaP_Intel
Moderator
1,254 Views

Hi,


Thanks for accepting our solution. If you need any additional information, please post a new question as this thread will no longer be monitored by Intel.


Thanks and Regards,

Pendyala Sesha Srinivas


0 Kudos
Reply