0

I'm using Jon Skeet's Misc Util library with Marc's Operator generic math class. I'm finding precision issues that I wouldn't otherwise find if I did the math normally.

For example, I find an error of something like .0001 when computing vector cross products compared to the regular float type operators.

Is this to be expected?

[Test]
public static void Reproduce_OperatorT_Issue()
{
    float termFive = Operator<float>.Multiply(5.3f, 56.0f);
    float termSix = Operator<float>.Multiply(6.5f, 55.0f);

    float newZ = Operator<float>.Subtract(termFive, termSix);

    Assert.AreEqual(newZ, 5.3f * 56.0f - 6.5f * 55.0f);
}

Output: Expected: -60.6999817f But was: -60.6999893f

HelloKitty
  • 64
  • 6
  • What are the specific numbers you are running? – xdhmoore Nov 22 '15 at 07:09
  • Please provide [a good, _minimal_, _complete_ code example](http://stackoverflow.com/help/mcve) that reliably reproduces your problem. – Peter Duniho Nov 22 '15 at 07:46
  • @PeterDunhino Are you aware of the "\[mcve]" tag? If not, try it, it'll save you a lot of typing. – Yuval Itzchakov Nov 22 '15 at 07:48
  • @YuvalItzchakov I was not, sorry about that. I have posted an example. This is my first question on here. I figured someone who had used MiscUtil by Jon Skeet might have encountered it or something. It's really an issue. – HelloKitty Nov 22 '15 at 08:02
  • This is just another "why is my floating point calculations not producing the same results" question, there are many questions here on SO about this. Short story is that the compiler, if it computes something as a constant, is not required to be limited by the precision of the runtime or of the variables being used. Most likely the constant that can be computed in the `AreEqual` call is done by the compiler at higher precision. Additionally, the CPU itself has higher precision internal registers, and the act of dumping a value to a IEEE format variable can also truncate precision. – Lasse V. Karlsen Nov 22 '15 at 09:37
  • You simply cannot rely on float having this kind of precision available for you across all calculations. – Lasse V. Karlsen Nov 22 '15 at 09:38
  • @YuvalItzchakov - How does the "[mcve]" tag work? – Enigmativity Nov 22 '15 at 09:41
  • @YuvalItzchakov - Oh... – Enigmativity Nov 22 '15 at 09:41
  • @Enigmativity LOL. I just discovererd it last week and was like "WHAT? All those times that I had to write manually and copy the link", don't think many people know about that. – Yuval Itzchakov Nov 22 '15 at 09:42
  • @Enigmativity You also have "\[ask]" for "How to Ask". – Yuval Itzchakov Nov 22 '15 at 09:42
  • @LasseV.Karlsen That seems reasonable but I only added those literals there for the sake of the showing some code. It will fail even if they're not literals. – HelloKitty Nov 22 '15 at 09:44

1 Answers1

0

This appears to be in line with the specification for floating types 4.1.6 Floating point types which is unfortunate. JIT appears to do double precision if needed but I suppose JIT will not do the same thing for those expressions in Operator which is the only explanation I can come up with for these precision issues.

Edit: As noted by others in the comments both the C# compiler, CLR and JIT have liberal control over floating points and what they do with them so there is no promise that values will be equivalent.

HelloKitty
  • 64
  • 6
  • The right hand value is actually going to be computed by the C# compiler which is also permitted to do the arithmetic at higher precision. [There is no requirement that it need behave the exactly the same as the JIT or the runtime.](http://stackoverflow.com/a/8795656/517852) – Mike Zboray Nov 22 '15 at 09:32
  • @mikez I see, but I only added those values in as literals for the test. It fails in both cases whether they're literal or not. – HelloKitty Nov 22 '15 at 09:42