why system providing routies will provide different result in C++ and Fortran 
Author Message
 why system providing routies will provide different result in C++ and Fortran

Now I make some converting- convert some fortran program to C++. I am
amazing about the little difference product by the C++ and fortran
program.

And after I check it deeply, I found that the + - * / operation does
not produce any difference. In C++ and Fortran, these operation will
give out identical result. So what I doubt is the system providing
routins such as exp, sqrt.

It definetly not a strange problem that in C++ and fortran, these
function will produce different result. But just because language
difference, they produce different result? or it is because the
difference in these function's implemention that make they producing
different result?

I write this message just wondering why they are different, and second
purpose is just complaining for these difference make me feel difficult
in converting Fortran code to C++.



Sat, 01 Mar 2008 03:00:50 GMT  
 why system providing routies will provide different result in C++ and Fortran


Quote:
> It definetly not a strange problem that in C++ and fortran, these
> function will produce different result. But just because language
> difference, they produce different result? or it is because the
> difference in these function's implemention that make they producing
> different result?

Well, you don't actually say what the difference is. Nor do you show any
actual code. Between the two things, it is pretty much impossible to
give a definitive answer. For example, your list of possible causes
doesn't have anything like "user write code that didn't mean what he
thought it meant." There are plenty of ways for that to happen; some of
them involve misunderstanding of precision issues. Although I am
operating based on *VERY* little data, I'd place this pretty high on my
list of likely explanations. Indeed, the biggest piece of data I have is
the lack of data, which I might interpret as a failure to understand how
such things can be important.

You also didn't specify what you mean by "C++" and "Fortran". Have you
tried this for very compiler on every operating system (of course, I
know the answer to that)? Or are you referring to results from some
particular compiler? It makes a big difference. Some things are
properties of the language. Other things are properties of specific
compilers.

In particular, the language specifies things like whether a particular
literal constant is interpreted as single or double precision; that can
be a difference between C++ and Fortran. A specific compiler includes
the actual implementation of function libraries; that has nothing to do
with C++ vs Fortran. Different compilers for the same language can have
different function libraries, yet compilers for the different languages
might share parts of the same function library.

I've written a lot of words for what I'm afraid is little in the way of
concrete answer. I suppose the short version is that if you want a
precise answer, you need to ask a precise question.

--
Richard Maine                       |  Good judgment comes from experience;
email: my first.last at org.domain  |  experience comes from bad judgment.
org: nasa, domain: gov              |        -- Mark Twain



Sat, 01 Mar 2008 03:23:18 GMT  
 why system providing routies will provide different result in C++ and Fortran

Quote:
> Now I make some converting- convert some fortran program to C++. I am
> amazing about the little difference product by the C++ and fortran
> program.

> And after I check it deeply, I found that the + - * / operation does
> not produce any difference. In C++ and Fortran, these operation will
> give out identical result. So what I doubt is the system providing
> routins such as exp, sqrt.

> It definetly not a strange problem that in C++ and fortran, these
> function will produce different result. But just because language
> difference, they produce different result? or it is because the
> difference in these function's implemention that make they producing
> different result?

There may be diferences in the quality of the implementation of the
functions. That would be surprising for good implementions of both
languages. If a vendor has compilers for both languages they will
tend to reuse the code so there will be no differences.

Quote:
> I write this message just wondering why they are different, and second
> purpose is just complaining for these difference make me feel difficult
> in converting Fortran code to C++.

You may be seeing differences in the order of evaluation of more
complex expressions. This will result in different roundoff errors.
Fortran compilers are allowed considerable freedom to rearrange
expressions.

Different orders of evaluation are common in Fortran when different
levels of optimization are requested by the user.

C and Fortran have subtle differences in their rules for when type
conversions are done if you have mixed precision expressions which
will then result if different roundoff. It is possible that the
different systems have chosen different rounding options for the
hardware. This may also involve the compiler using a hidden extended
precision mode for its temporaries.

Changes due to differing roundoff are common in Fortran when changing
compiler, either a different vendor, just a newer version or even only
a different optimization level.

There are many subtle ways for arithmetic to produce slightly diferent
result beyond the ways you have mentioned. I have listed a few.

If the differences accumulate you may be seeing the symptoms of an
unstable algorithm in which case your problems are not with choice
of programming language but rather of numerical method.

Ask google about a paper called
"What every computer scientist should know about floating-point"
for a nice introducion to the topic.



Sat, 01 Mar 2008 03:26:24 GMT  
 why system providing routies will provide different result in C++ and Fortran
c/c++ built in maths functions will convert/promote any argument to double
and
return a double result.

literal numeric constants (e.g. 2.0) in fortran are c++ float.
in c++ they are double.

trig function evaluation of sin/cos/tan of 90 degrees
in fortran (of c++ float) returns a result with cos and tan in the wrong
quadrant.
this is not a defect of fortran. try single precision (32 bit) trig
evaluation
in most languages and the cos and tan results will return results
in the wrong quadrant.

you need to develop an understanding of floating points maths.

the later post points to a very good paper on this whole issue.


Quote:
> Now I make some converting- convert some fortran program to C++. I am
> amazing about the little difference product by the C++ and fortran
> program.

> And after I check it deeply, I found that the + - * / operation does
> not produce any difference. In C++ and Fortran, these operation will
> give out identical result. So what I doubt is the system providing
> routins such as exp, sqrt.

> It definetly not a strange problem that in C++ and fortran, these
> function will produce different result. But just because language
> difference, they produce different result? or it is because the
> difference in these function's implemention that make they producing
> different result?

> I write this message just wondering why they are different, and second
> purpose is just complaining for these difference make me feel difficult
> in converting Fortran code to C++.



Sat, 01 Mar 2008 05:30:22 GMT  
 why system providing routies will provide different result in C++ and Fortran

Quote:

> c/c++ built in maths functions will convert/promote any argument to double
> and
> return a double result.

> literal numeric constants (e.g. 2.0) in fortran are c++ float.
> in c++ they are double.

> trig function evaluation of sin/cos/tan of 90 degrees
> in fortran (of c++ float) returns a result with cos and tan in the wrong
> quadrant.

I'm not sure what you mean by 'the wrong quadrant'. The trig functions return a
number between -1 and 1 (SIN and COS) or -Inf and +Inf (TAN); there is no notion
of 'quadrant', since the return value is not an angular measure.

If you instead mean the inverse trig functions, then the Fortran standard is
quite explicit about which quandrant the returned angular measure falls within.
To get a 'correct' quadrant, you should be using the ATAN2() function (there is
no ACOS2 or ASIN2, since there is no sensible way to define two-argument
variants of ACOS and ASIN).

cheers,

Rich



Sat, 01 Mar 2008 05:43:48 GMT  
 why system providing routies will provide different result in C++ and Fortran

Quote:

> Now I make some converting- convert some fortran program to C++. I am
> amazing about the little difference product by the C++ and fortran
> program.

> And after I check it deeply, I found that the + - * / operation does
> not produce any difference. In C++ and Fortran, these operation will
> give out identical result. So what I doubt is the system providing
> routins such as exp, sqrt.

[snip]

Without seeing your test programs, it is difficult to guess, but here
is one idea. I've tested the 4.1.0 versions of gcc (C) and gfortran
(Fortran).

consider the following programs:

C:\gfortran>type foo1.c
#include <stdio.h>
#include <math.h>
int i;
main(){
  for(i=0;i<6;i++){
    printf(" %2d %17.15f\n",i,sqrt(i));
  }

Quote:
}

C:\gfortran>type foo2.f
      do i=0,5
        print '(1x,i2,1x,f17.15)',i,sqrt(real(i))
      end do
      end

C:\gfortran>type foo3.f
      do i=0,5
        print '(1x,i2,1x,f17.15)',i,sqrt(dble(i))
      end do
      end

C:\gfortran>C:\gfortran>make

C:\gfortran>gcc foo1.c -Iinclude -o foo1

C:\gfortran>gfortran foo2.f -o foo2

C:\gfortran>gfortran foo3.f -o foo3
C:\gfortran>foo1
  0 0.000000000000000
  1 1.000000000000000
  2 1.414213562373095
  3 1.732050807568877
  4 2.000000000000000
  5 2.236067977499790

C:\gfortran>foo2
  0 0.000000000000000
  1 1.000000000000000
  2 1.414213538169861
  3 1.732050776481628
  4 2.000000000000000
  5 2.236068010330200

C:\gfortran>foo3
  0 0.000000000000000
  1 1.000000000000000
  2 1.414213562373095
  3 1.732050807568877
  4 2.000000000000000
  5 2.236067977499790

C:\gfortran>

In the C program, sqrt returns a "double". In the Fortran program, the
return type is the same as the type of the argument. In the first
program, it is real or "float" in C terminology. In the second program
it is double precision or "double" in C.

-- Elliot



Sat, 01 Mar 2008 06:57:38 GMT  
 why system providing routies will provide different result in C++ and Fortran
Quote:

> c/c++ built in maths functions will convert/promote any argument to double
> and
> return a double result.

This is true of "traditional" C and C++.  Most C++ compilers support
versions corresponding to the various floating point data types.
C differs from C++ in supporting "type generic" intrinsic functions
<tgmath.h>, somewhat analogous to Fortran.  Many C++ compilers support
mixing it in as an extension.  OP may have meant to exclude it by
specifying C++.
Quote:

> literal numeric constants (e.g. 2.0) in fortran are c++ float.
> in c++ they are double.

I agree that the difference in default types (double in C++, commonly
single in Fortran) is among the issues OP should be considering.

It is not unusual for C and Fortran to share the math function library,
in which case difference in results is attributable to{*filter*}pit error.



Sat, 01 Mar 2008 11:19:58 GMT  
 why system providing routies will provide different result in C++ and Fortran

Quote:


>> c/c++ built in maths functions will convert/promote any argument to
>> double and
>> return a double result.
> This is true of "traditional" C and C++.  

You mean like C89?  How many C99 compilers do you know of?
About as many as F2003 compilers?

Quote:
> Most C++ compilers support
> versions corresponding to the various floating point data types.
> C differs from C++ in supporting "type generic" intrinsic functions
> <tgmath.h>, somewhat analogous to Fortran.  Many C++ compilers support
> mixing it in as an extension.  OP may have meant to exclude it by
> specifying C++.
>> literal numeric constants (e.g. 2.0) in fortran are c++ float.
>> in c++ they are double.
> I agree that the difference in default types (double in C++, commonly
> single in Fortran) is among the issues OP should be considering.

Well, the default type in C is int in the cases where it
matters.  Otherwise variables have to be declared either double
or float.

Quote:
> It is not unusual for C and Fortran to share the math function library,
> in which case difference in results is attributable to{*filter*}pit error.

Yes.  Or even the whole C library.

-- glen



Sat, 01 Mar 2008 12:13:48 GMT  
 why system providing routies will provide different result in C++ and Fortran
Quote:



>>> c/c++ built in maths functions will convert/promote any argument to
>>> double and
>>> return a double result.

>> This is true of "traditional" C and C++.  

> You mean like C89?  How many C99 compilers do you know of?
> About as many as F2003 compilers?

No, like K&R, although C89 supports that style and adds (not fully
mandatory) support for float and long double math library.
Quote:

>> I agree that the difference in default types (double in C++, commonly
>> single in Fortran) is among the issues OP should be considering.

> Well, the default type in C is int in the cases where it
> matters.  Otherwise variables have to be declared either double
> or float.

In traditional C, there is no option to support float arguments; they
are promoted to double. In the absence of prototype, that promotion
remains a default.  Likewise, float expression evaluation was promoted
to double, and there are still compilers which do that in their usual
language standard compliance mode.  Certainly, reliance on defaults is
not satisfactory practice, but OP appears to criticize Fortran for
having defaults differing from typical C++ practice.


Sat, 01 Mar 2008 21:56:26 GMT  
 why system providing routies will provide different result in C++ and Fortran

Quote:

> glen herrmannsfeldt wrote


>>>> c/c++ built in maths functions will convert/promote any argument to
>>>> double and return a double result.
>>> This is true of "traditional" C and C++.  
>> You mean like C89?  How many C99 compilers do you know of?
>> About as many as F2003 compilers?
> No, like K&R, although C89 supports that style and adds (not fully
> mandatory) support for float and long double math library.

With the math.h header file the arguments will be converted to
double.   The sqrtf() man pages I find seem to indicate C99.
I believe they are required in C99, and optional in C89.

To get back on topic, the early (before 1966) Fortran compilers
required function names to end in f, and array names not to end
in f.  So Fortran had sqrtf() and sinf().

Quote:
>>> I agree that the difference in default types (double in C++, commonly
>>> single in Fortran) is among the issues OP should be considering.
>> Well, the default type in C is int in the cases where it
>> matters.  Otherwise variables have to be declared either double
>> or float.
> In traditional C, there is no option to support float arguments; they
> are promoted to double. In the absence of prototype, that promotion
> remains a default.  Likewise, float expression evaluation was promoted
> to double, and there are still compilers which do that in their usual
> language standard compliance mode.  Certainly, reliance on defaults is
> not satisfactory practice, but OP appears to criticize Fortran for
> having defaults differing from typical C++ practice.

Anyway, yes, with C and C++ it is most likely that floating point
expressions and math library functions are done in double precision,
where in Fortran, unless one specifically asks, in single precision.

Though the popular processors do everything in double precision
(or more), anyway.

-- glen



Sat, 01 Mar 2008 23:54:39 GMT  
 why system providing routies will provide different result in C++ and Fortran

Quote:
> Though the popular processors do everything in double precision
> (or more), anyway.

If you mean x86 by that, I was under the impression that they can
be constrained to actually implement IEEE 754 semantics at the two
lower precisions - certainly when generating SSE2 code, but even
when generating x87 code. Am I wrong?

        Jan



Sun, 02 Mar 2008 15:38:56 GMT  
 why system providing routies will provide different result in C++ and Fortran

Quote:

>> Though the popular processors do everything in double precision
>> (or more), anyway.
> If you mean x86 by that, I was under the impression that they can
> be constrained to actually implement IEEE 754 semantics at the two
> lower precisions - certainly when generating SSE2 code, but even
> when generating x87 code. Am I wrong?

There are control register bits that specify the number
of fraction bits to generate for some operations.
To do it right, you would need to change that fairly often,
and I believe it doesn't apply to all operations.

-- glen



Sun, 02 Mar 2008 18:18:29 GMT  
 why system providing routies will provide different result in C++ and Fortran
Here is a test program

program
---------

program trigtest
implicit none
integer , dimension(15) :: angles= &
  (/-1,0,1,29,30,31,44,45,46,59,60,61,89,90,91/)
real :: pi
real :: r
integer :: i
  pi=4.0*atan(1.0)
  do i=1,15
    r=pi*angles(i)/180
    print *,angles(i),' ',sin(r),' ',cos(r),' ',tan(r)
  end do
end program trigtest

end program
--------------

Here is the intel output

          -1   -1.7452406E-02    0.9998477       -1.7455066E-02
           0    0.0000000E+00     1.000000        0.0000000E+00
           1    1.7452406E-02    0.9998477        1.7455066E-02
          29    0.4848096        0.8746197        0.5543091
          30    0.5000000        0.8660254        0.5773503
          31    0.5150381        0.8571673        0.6008607
          44    0.6946584        0.7193398        0.9656888
          45    0.7071068        0.7071068         1.000000
          46    0.7193398        0.6946583         1.035530
          59    0.8571673        0.5150381         1.664279
          60    0.8660254        0.5000000         1.732051
          61    0.8746197        0.4848096         1.804048
          89    0.9998477        1.7452383E-02     57.29004
          90     1.000000       -4.3711388E-08   -2.2877332E+07
          91    0.9998477       -1.7452471E-02    -57.28975

note the sign at 90 degrees of the cos and tan.

we've found we get similar results
with all of the compilers we currently use.

it is one of the examples that Jane Sleightholme
and I have developed to help beginners
understand some of the problems they will
encounter with floating point maths.


Quote:

>> c/c++ built in maths functions will convert/promote any argument to
>> double and
>> return a double result.

>> literal numeric constants (e.g. 2.0) in fortran are c++ float.
>> in c++ they are double.

>> trig function evaluation of sin/cos/tan of 90 degrees
>> in fortran (of c++ float) returns a result with cos and tan in the wrong
>> quadrant.

> I'm not sure what you mean by 'the wrong quadrant'. The trig functions
> return a number between -1 and 1 (SIN and COS) or -Inf and +Inf (TAN);
> there is no notion of 'quadrant', since the return value is not an angular
> measure.

> If you instead mean the inverse trig functions, then the Fortran standard
> is quite explicit about which quandrant the returned angular measure falls
> within. To get a 'correct' quadrant, you should be using the ATAN2()
> function (there is no ACOS2 or ASIN2, since there is no sensible way to
> define two-argument variants of ACOS and ASIN).

> cheers,

> Rich



Sun, 02 Mar 2008 23:36:30 GMT  
 why system providing routies will provide different result in C++ and Fortran
I've just run the c++ example below with
cygwin g++ 3.4.4.

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
  float angle_r;
  int angle_d;
  int angles [] ={ -1, 0, 1,
                  29,30,31,
                  44,45,46,
                  59,60,61,
                  89,90,91 };

  float pi=4*atan(1.0);

  for(int i=0;i<15;i++)
  {
    angle_d=angles[i];
    angle_r=angle_d*pi/180;
    cout << angle_d << "  " ;
    cout.width(15);cout.precision(10);cout << sin(angle_r)<< " " ;
    cout.width(15);cout.precision(10);cout << cos(angle_r)<< " " ;
    cout.width(15);cout.precision(10);cout << tan(angle_r)<< " " << endl;
  }

  return 0;

Quote:
}

this now returns the following output.

-1    -0.0174524063    0.9998476952  -0.01745506479
0                0               1               0
1     0.0174524063    0.9998476952   0.01745506479
29     0.4848096152    0.8746197099    0.5543090439
30     0.5000000126    0.8660253965    0.5773502886
31     0.5150381048    0.8571672827    0.6008606666
44     0.6946583715    0.7193397993    0.9656887777
45     0.7071067966    0.7071067657     1.000000044
46     0.7193398297    0.6946583401     1.035530401
59     0.8571673052    0.5150380674     1.664279515
60     0.8660254184    0.4999999748     1.732050924
61     0.8746197311     0.484809577     1.804047966
89     0.9998476956   0.01745238308     57.29003832
90                1   -4.371139e-08    -22877332.43
91      0.999847694  -0.01745247049     -57.2897513

I stopped teaching c++ in 2002. when
did this behaviour come into C++ compilers?


Quote:

>> c/c++ built in maths functions will convert/promote any argument to
>> double and
>> return a double result.
> This is true of "traditional" C and C++.  Most C++ compilers support
> versions corresponding to the various floating point data types.
> C differs from C++ in supporting "type generic" intrinsic functions
> <tgmath.h>, somewhat analogous to Fortran.  Many C++ compilers support
> mixing it in as an extension.  OP may have meant to exclude it by
> specifying C++.

>> literal numeric constants (e.g. 2.0) in fortran are c++ float.
>> in c++ they are double.

> I agree that the difference in default types (double in C++, commonly
> single in Fortran) is among the issues OP should be considering.

> It is not unusual for C and Fortran to share the math function library, in
> which case difference in results is attributable to{*filter*}pit error.



Sun, 02 Mar 2008 23:43:10 GMT  
 why system providing routies will provide different result in C++ and Fortran

Quote:

> Here is a test program
[...]
>     r=pi*angles(i)/180
>     print *,angles(i),' ',sin(r),' ',cos(r),' ',tan(r)
[...]
>           61    0.8746197        0.4848096         1.804048
>           89    0.9998477        1.7452383E-02     57.29004
>           90     1.000000       -4.3711388E-08   -2.2877332E+07
>           91    0.9998477       -1.7452471E-02    -57.28975

> note the sign at 90 degrees of the cos and tan.

Yes.  What's wrong with it?

Clearly, r is an approximation to pi/4 in any limited-precision
calculation, and thus these values are values for some angle that's
nearly but not exactly 90 degrees.  Thus, I can't see any reason to
claim that either sign would be wrong here, unless you have some
specific claim about what side of pi/4 r happens to lie on.

- Brooks

--
The "bmoses-nospam" address is valid; no unmunging needed.



Mon, 03 Mar 2008 04:07:55 GMT  
 
 [ 25 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Why online libraries do not provide journal articles?

2. FPSC provides system migrations/conversion using Micro Focus on Unix platforms

3. Again: linking between C++ and Fortran results in incorrect result

4. same progams give different results, why?

5. APL Providing Mineralogic Mapper for NASA's 2005 Orbiter Mission

6. How to provide a Windows printer selection for host printing

7. ANNOUNCEMENT - NEW DBWIRED / GITANO SOFTWARE SERVICES PROVIDED......

8. Report Template from Browse that provides a Report with Word and Excel output

9. MySQL Database Now Provides Full Transaction Support

10. Using a string to provide input to a template variable

11. Please provide unsubscribe information

12. Best way to provide security to clipper application

 

 
Powered by phpBB® Forum Software