3

This does not answer the question.

I ran the same exact code in Java & C# and it gave two differents results.

Why? As the doubles in both languages have the exact same specifications :

double is a type that represents 64-bit IEEE 754 floating-point number in Java

double is a type that represents 64-bit double-precision number in IEEE 754 format in C#.


Java

double a = Math.pow(Math.sin(3), 2);
double b = Math.pow(Math.cos(3), 2);
System.out.println(a);   // 0.01991485667481699
System.out.println(b);   // 0.9800851433251829
System.out.println(a+b); // 0.9999999999999999

C#

double a = Math.Pow(Math.Sin(3), 2);
double b = Math.Pow(Math.Cos(3), 2);
Console.WriteLine(a);   // 0.019914856674817
Console.WriteLine(b);   // 0.980085143325183
Console.WriteLine(a+b); // 1
Community
  • 1
  • 1
Yassin Hajaj
  • 21,337
  • 9
  • 51
  • 89
  • 3
    I have a suspicion this is more to do with the console output rounding out the numbers rather than the underlying maths. – Paolo Nov 16 '15 at 19:57
  • 3
    Are you sure the implementations of `Sin` and `Cos` are the same? – RealSkeptic Nov 16 '15 at 19:59
  • @RealSkeptic not sure at all. Paolo Yes, that is what the teacher told me also but I wanted to have a proper explanation. – Yassin Hajaj Nov 16 '15 at 20:02
  • @RealSkeptic It seems that it comes from a native method in Java. And I think it is the same in C# and therefor I can not find the exact implementation. – Yassin Hajaj Nov 16 '15 at 20:05

3 Answers3

7

It's just the precision that C# is using with the writeLine method. See https://msdn.microsoft.com/en-us/library/dwhawy9k.aspx#GFormatString where it specifies that the G format specifier gives 15-digit precision.

If you write:

Console.WriteLine(a.ToString("R"));

it prints 0.019914856674816989.

M A
  • 71,713
  • 13
  • 134
  • 174
0

The root of it is that floating point numbers are imprecise and calculations can't even really be relied upon to be deterministic. But they're close.

Most likely the difference is probably because the CLR is allowed to work with doubles as 80 bit numbers internally. You don't ever see more than 64 bits, however the processor will work with 80. I'm unsure how Java handles floating point numbers internally. It could possibly be the same.

There's tons on the topic, but here's some random light reading from Google which may be of interest.

Community
  • 1
  • 1
Glorin Oakenfoot
  • 2,455
  • 1
  • 17
  • 19
0

IEEE754 has a distiction between required operations and optional operations:

  • required operations, like addition, subtraction, etc must be exactly rounded
  • optional operations are not required to be exactly rounded, and the list of these operations includes all trigonometric functions (and others), they are let to the implementation

So you have no guarantees from the standard that sin and cos implementation should match between implementations.

More infomations here or here.

Jack
  • 131,802
  • 30
  • 241
  • 343