Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- Intel Community
- Software Development Tools (Compilers, Debuggers, Profilers & Analyzers)
- Intel® Fortran Compiler
- Fortran vs Visual C++ returns diffent values from pow function

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

Highlighted
##

Pugliesi__Raphael

Beginner

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-09-2018
10:40 AM

5 Views

Fortran vs Visual C++ returns diffent values from pow function

Dear all,

We faced off a problem with pow function between Fortran and Visual C++. You can find attached an image about this issue. We want to achievi the same result from Fortran to C++.

Any help could be good.

Best regards.

7 Replies

Highlighted
##

Eugene_E_Intel

Employee

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-09-2018
01:33 PM

5 Views

Hello,

Hello,

I believe that float (and Fortran default real) has 6 digits of precision, so the "a" assignment already loses information. "b" has similar limitation. You notice that the outputs up to 6 digits are pretty close. I recommend you also print "a", to see, if there's a difference even before the power is computed.

Thank you,

--Eugene

Eugene Epshteyn

Highlighted
##

Steve_Lionel

Black Belt

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-09-2018
01:37 PM

5 Views

Do you understand that you

Do you understand that you are doing this computation in single precision, good to only about six decimal places? All those extra digits in the constant are wasted. When I try this in double precision, the Fortran answer you get is closer to the double-precision result than the C answer.

While I might at first suggest that it's the C result that is worse, I think your expectations are unrealistic considering the use of single precision.

Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran

Highlighted
##

TimP

Black Belt

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-10-2018
04:37 AM

5 Views

If you use the pow() function

If you use the pow() function and constants without suffix f in C, those are typed double. For C float, powf() may be available, but you have no assurance that it doesn't use pow(). As you saw, exponentiation for large or small magnitude arguments may be inaccurate in the low order 4 bits, although the scalar one in ifort may be a little better.

For the case x**.25d0, sqrt(sqrt(x)) should be faster (at least in the non-vectorized case) and more accurate.

Highlighted
##

Pugliesi__Raphael

Beginner

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-12-2018
03:46 AM

5 Views

Dear all,

Dear all,

Thank you for all answers.

I know the limits about single precision calculation, but i must to performe the same results in C as i found in Fortran program.

Eugene, when i print out the variable "a" i got the same constante value already informed (you can find in attachments).

Steve and Tim, when i change the fortran code constants to double

program main real*4 a real*4 b a = 0.0000311759686155710369348526000976562500 b =(a / .0002d0)**.25d0 write(*,'(F50.40)') b end program main

i got the same result as C, but i need in C the same result as Fortran (knowing about the numerical problems). I did the changes in C code to float type but i got the same results as double type.

Best regards.

Highlighted
##

Eugene_E_Intel

Employee

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-12-2018
04:15 AM

5 Views

I believe "real*4" is still

I believe "real*4" is still equivalent to "float".

You need "real*8" for "double".

Also, you need to add suffix "_8" to your literal constant, otherwise it would still be treated as single precision:

a = 0.0000311759686155710369348526000976562500_8

You would need to add the suffix to all literal floating point constants you use in the code.

(Before I get beaten up for using non-standard way to specify precision, I'd like to point you to this article that describes a standard way to specify precision in Fortran: https://software.intel.com/en-us/blogs/2017/03/27/doctor-fortran-in-it-takes-all-kinds )

Eugene Epshteyn

Highlighted
##

FortranFan

Valued Contributor III

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-12-2018
09:15 AM

5 Views

Quote:Pugliesi, Raphael wrote

Pugliesi, Raphael wrote:

.. but i need in C the same result as Fortran (knowing about the numerical problems). I did the changes in C code to float type but i got the same results as double type. ..

@Pugliesi, Raphael,

Given the differences between C and Fortran re: how literal constants are treated and consequent potential for mixed-mode arithmetic, can you not employ consistent use of floating-point "double" in both sides of your mixed-language code? You can then achieve the "same" result. See below:

module kinds_m use, intrinsic :: iso_c_binding, only : WP => c_double end module module m ! Work with defined kinds in Fortran use kinds_m, only : WP use, intrinsic :: iso_fortran_env, only : output_unit implicit none contains subroutine Fsub() bind(C, name="Fsub") real(WP) :: a real(WP) :: b real(WP), parameter :: D = 0.0002_wp real(WP), parameter :: E = 0.25_wp a = 0.0000311759686155710369348526000976562500_wp; b = (a/D)**E; write( output_unit, fmt="(g0,g60.40)" ) "b (Fortran): ", b return end subroutine Fsub end module

#include <iostream> #include <cmath> using namespace std; extern "C" { // Prototype for a Fortran subprogram void Fsub(void); } int main( ) { double a; double b; const double D = 0.0002; const double E = 0.25; a = 0.0000311759686155710369348526000976562500; b = std::pow((a/D), E); cout.precision(40); cout << "b (C++): " << fixed << b << endl; Fsub(); return 0; }

With the use of Intel Fortran as well as Microsoft C/C++ compiler, the above yields upon execution:

b (C++): 0.6283440254388115153716398708638735115528 b (Fortran): 0.6283440254388115153716398708638735115530

Highlighted
##

Johannes_Rieke

New Contributor III

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-12-2018
09:47 AM

5 Views

Hi, if you want single

**f**" (without underscore, e.g. http://en.cppreference.com/w/cpp/language/floating_literal). I don't know how C/C++ handles implicit type casting, so one should be careful by using functions as pow().

For more complete information about compiler optimizations, see our Optimization Notice.