Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. double accuracy and equality

double accuracy and equality

Scheduled Pinned Locked Moved C#
helptestingbeta-testingtutorialquestion
4 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    vineas
    wrote on last edited by
    #1

    I'm working on a project with some pretty math intensive calculations that must output double values. After much testing, it was determined that we have an accuracy out to 10 digits after the decimal point. This is adequate for what I'm working with so we kept going forward. Now, in the next phase of the project, comparisons have to be made between two structures that contain the double results, so I overloaded Equals() to do a comparison to the tested accuracy. Immediately I found some big problems with this. Because of the way Equals() is determined, I run into the problem where the following is true: A==B, B==C, A!=C. I'm a bit stumped on how to fix this. There must be a way, but I'm not really seeing anything. I created the following test code to illustrate my problem: using System; using System.Collections; namespace TestIt { class Class1 { [STAThread] static void Main(string[] args) { SomeStruct val1 = new SomeStruct(1.0); SomeStruct val2 = new SomeStruct(1.0); SomeStruct val3 = new SomeStruct(1.00000000009999); SomeStruct val4 = new SomeStruct(0.99999999999); Console.WriteLine("Starting . . ."); if (val1.Equals(val2)) Console.WriteLine("val1 == val2"); if (val2.Equals(val3)) Console.WriteLine("val2 == val3"); if (val1.Equals(val3)) Console.WriteLine("val1 == val3"); if (val1.Equals(val4)) Console.WriteLine("val1 == val4"); if (val3.Equals(val4)) Console.WriteLine("val3 == val4"); // problem, this doesn't happen Console.WriteLine("Done"); } public struct SomeStruct { private static double accuracy = 0.0000000001; public double Value; public SomeStruct(double val) { Value = val; } public override bool Equals(object obj) { if (obj is SomeStruct) return (Math.Abs(Value - ((SomeStruct)obj).Value) < accuracy); return false; } } } } Anyone have any ideas? ----- In the land of the blind, the one eyed man is king.

    M G 2 Replies Last reply
    0
    • V vineas

      I'm working on a project with some pretty math intensive calculations that must output double values. After much testing, it was determined that we have an accuracy out to 10 digits after the decimal point. This is adequate for what I'm working with so we kept going forward. Now, in the next phase of the project, comparisons have to be made between two structures that contain the double results, so I overloaded Equals() to do a comparison to the tested accuracy. Immediately I found some big problems with this. Because of the way Equals() is determined, I run into the problem where the following is true: A==B, B==C, A!=C. I'm a bit stumped on how to fix this. There must be a way, but I'm not really seeing anything. I created the following test code to illustrate my problem: using System; using System.Collections; namespace TestIt { class Class1 { [STAThread] static void Main(string[] args) { SomeStruct val1 = new SomeStruct(1.0); SomeStruct val2 = new SomeStruct(1.0); SomeStruct val3 = new SomeStruct(1.00000000009999); SomeStruct val4 = new SomeStruct(0.99999999999); Console.WriteLine("Starting . . ."); if (val1.Equals(val2)) Console.WriteLine("val1 == val2"); if (val2.Equals(val3)) Console.WriteLine("val2 == val3"); if (val1.Equals(val3)) Console.WriteLine("val1 == val3"); if (val1.Equals(val4)) Console.WriteLine("val1 == val4"); if (val3.Equals(val4)) Console.WriteLine("val3 == val4"); // problem, this doesn't happen Console.WriteLine("Done"); } public struct SomeStruct { private static double accuracy = 0.0000000001; public double Value; public SomeStruct(double val) { Value = val; } public override bool Equals(object obj) { if (obj is SomeStruct) return (Math.Abs(Value - ((SomeStruct)obj).Value) < accuracy); return false; } } } } Anyone have any ideas? ----- In the land of the blind, the one eyed man is king.

      M Offline
      M Offline
      Michael Potter
      wrote on last edited by
      #2

      I think you will find val3 - val4 is greater then accuracy. The program is working as written. You will have to change the value of accuracy to get the results you want. If you want to use accuracy as defined, you may want to truncate all your numbers to 10 digits before testing for equality. Take a look at double.Epsilon. It contains a number you can use to test for equality on doubles but, it carries it to the least significant digit. Also, take a look at the Decimal structure. It may suit your needs out of the box.

      V 1 Reply Last reply
      0
      • V vineas

        I'm working on a project with some pretty math intensive calculations that must output double values. After much testing, it was determined that we have an accuracy out to 10 digits after the decimal point. This is adequate for what I'm working with so we kept going forward. Now, in the next phase of the project, comparisons have to be made between two structures that contain the double results, so I overloaded Equals() to do a comparison to the tested accuracy. Immediately I found some big problems with this. Because of the way Equals() is determined, I run into the problem where the following is true: A==B, B==C, A!=C. I'm a bit stumped on how to fix this. There must be a way, but I'm not really seeing anything. I created the following test code to illustrate my problem: using System; using System.Collections; namespace TestIt { class Class1 { [STAThread] static void Main(string[] args) { SomeStruct val1 = new SomeStruct(1.0); SomeStruct val2 = new SomeStruct(1.0); SomeStruct val3 = new SomeStruct(1.00000000009999); SomeStruct val4 = new SomeStruct(0.99999999999); Console.WriteLine("Starting . . ."); if (val1.Equals(val2)) Console.WriteLine("val1 == val2"); if (val2.Equals(val3)) Console.WriteLine("val2 == val3"); if (val1.Equals(val3)) Console.WriteLine("val1 == val3"); if (val1.Equals(val4)) Console.WriteLine("val1 == val4"); if (val3.Equals(val4)) Console.WriteLine("val3 == val4"); // problem, this doesn't happen Console.WriteLine("Done"); } public struct SomeStruct { private static double accuracy = 0.0000000001; public double Value; public SomeStruct(double val) { Value = val; } public override bool Equals(object obj) { if (obj is SomeStruct) return (Math.Abs(Value - ((SomeStruct)obj).Value) < accuracy); return false; } } } } Anyone have any ideas? ----- In the land of the blind, the one eyed man is king.

        G Offline
        G Offline
        Guffa
        wrote on last edited by
        #3

        You will get better results if you round each value and then compare them, instead of checking the sum of the rounding errors. Math.Round(this.Value, 10) == Math.Round(((SomeStruct)obj).Value, 10) --- b { font-weight: normal; }

        1 Reply Last reply
        0
        • M Michael Potter

          I think you will find val3 - val4 is greater then accuracy. The program is working as written. You will have to change the value of accuracy to get the results you want. If you want to use accuracy as defined, you may want to truncate all your numbers to 10 digits before testing for equality. Take a look at double.Epsilon. It contains a number you can use to test for equality on doubles but, it carries it to the least significant digit. Also, take a look at the Decimal structure. It may suit your needs out of the box.

          V Offline
          V Offline
          vineas
          wrote on last edited by
          #4

          Yes, val3 - val4 is greater than accuracy, but that leaves me with the problem that val3 == val1 is true, val1 == val4 is true, but val3 == val4 is false. A==B, B==C therefore A==C is a basic mathematical principal that this is breaking, and I'm afraid will cause problems, and I can't figure out a way around it. Truncation isn't quite right either, that way 1.0000000001 and 1.00000000009 wouldn't match up. I've since rewritten the equality method, to get much better results but no matter how I change it, I still can't get around that basic problem. BTW, I've thought about using the Decimal structure for internal calculations, but I don't know how much it would gain me when most of the intermediate results will be stored outside of my class and will be in double. ----- In the land of the blind, the one eyed man is king.

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups