1

I want to compare two doubles a and b in C# (where for example b has more decimal places) in the way that: if I round the number b to number of decimal places of a i should get the same number if they are the same. Example:

double a = 0.123;
double b = 0.1234567890;

should be same.

double a = 0.123457
double b = 0.123456789

should be same.

I cannot write

if(Math.Abs(a-b) < eps)

because I don't know how to calculate precision eps.

Dejan
  • 966
  • 1
  • 8
  • 26
  • Are you deciding the number of decimal places? – doctorlove Jul 31 '14 at 13:50
  • You may have set up your example wrong.. `a` is already "rounded" to the same number of decimal places as `b`, because `b` has MORE precision... so I'm not quite sure what you're asking. – entropic Jul 31 '14 at 13:50
  • A double does not include a concept of significant digits. It uses all the precision it has. consider e.g. `double a = 1.030;` – Captain Giraffe Jul 31 '14 at 13:51
  • 1
    This seems more like a question about significant digits. This page might help: [Formatting numbers with significant figures in C#](http://stackoverflow.com/questions/158172/formatting-numbers-with-significant-figures-in-c-sharp) – Jason Z Jul 31 '14 at 14:00

2 Answers2

1

If I have understood what you want you could just shift the digits before the decimal place til the "smaller" (i.e. one with least significant figures) is a integer, then compare: i.e. in some class...

static bool comp(double a, double b)
{
    while((a-(int)a)>0 && (b - (int)b)>0)
    {
        a *= 10;
        b *= 10;
    }
    a = (int)a;
    b = (int)b;
    return a == b;
}

Edit

Clearly calling (int)x on a double is asking for trouble since double can store bigger numbers than ints. This is better:

while((a-Math.Floor(a))>0 && (b - Math.Floor(b))>0)
//...
doctorlove
  • 18,872
  • 2
  • 46
  • 62
  • I think that this function is not good. For example, I have `b=1.63329` and when it is multiply 2 times with 10 I get `b=163.32899999999998`, so the while loop does not finish and numbers ends up in infinity. – Dejan Jul 31 '14 at 14:15
  • Fair point - the links in @JasonZ comments is the same in spirit - but using Math.Log finds what you would need to multiply by without getting in a mess with overflows etc – doctorlove Jul 31 '14 at 14:22
  • I bound maximum number of multiplication for example to 15, so the program can exit while loop. I tested it on several number and results looks fine. I will use this solution hopping that it will not produce some mess in future, since I needed this comparison for Unit testing. – Dejan Jul 31 '14 at 14:46
  • The Math.Log approach may be quicker. Good luck. Or look at the relative sizes. Something like `if (Math.Abs(x-y) < Math.Abs(x)*precision )` ... see http://accu.org/index.php/articles/1558 – doctorlove Jul 31 '14 at 15:02
0

double has epsilon double.Epsilon or set prefer error by hardcode, f.e. 0.00001

burning_LEGION
  • 13,246
  • 8
  • 40
  • 52