- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Please find the zip file which contains the modified source files.
Thanks and Regards,
Pendyala Sesha Srinivas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Do you have any news about the other doubts?
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
We are working on your issue. We will get back to you soon.
Thanks and Regards,
Pendyala Sesha Srinivas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page