6

I'm using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal.

0.1123456789
0.11234567891
0.11234567899

The 10 decimal limit is coming from my database, so I have to assume that the first number was already rounded, and therefore I can't simply round the others because the last one will round up.

I really just want to truncate the to 10 decimal places, but can't see how to do this either.

TheSean
  • 4,516
  • 7
  • 40
  • 50
  • Does this answer your question? [How to properly compare decimal values in C#?](https://stackoverflow.com/questions/5940222/how-to-properly-compare-decimal-values-in-c) – Michael Freidgeim Aug 01 '21 at 23:52

5 Answers5

11

The same way you'd compare floating point numbers. Here's some pseudocode, because I don't know the .NET call for absolute value, but it will essentially look like this (modify the constant for the precision needed):

if( Math.Abs( value1 - value2 ) < 0.0000000001 )
{
  // blah blah
}
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
Russell Newquist
  • 2,656
  • 2
  • 16
  • 18
8

What about multiplying by 10^10 and dropping the fractional part?

decimal x2 = Math.Truncate(x * 10000000000);
decimal y2 = Math.Truncate(y * 10000000000);
Assert.Equals(x2, y2);

EDIT: Changed to Math.Truncate by Aaron's suggestion. Thanks.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • 1
    Of course this will also be wrong for any value greater than 2^31 / 10000000000. – Aaron Nov 09 '09 at 15:01
  • Change it to Math.Truncate() instead of converting to int - you'll still lose a little top-end precision but it will be 'closer'. – Aaron Nov 09 '09 at 15:07
  • @Aaron - The example the OP showed would be for numbers less than 1, so this would work fine. – James Black Nov 09 '09 at 15:11
  • The DB field I'm trying to match is Decimal(28,10), so I'd like the test to be valid for all numbers that could be stored in the DB. But generally, I'm dealing with percentages so they are stored as 0-100. Thanks. – TheSean Nov 09 '09 at 15:31
1

Multiply by 10000000000, convert to an int, then divide by the same number.

That way you truncate the the excess digits.

You may want to add .5 * 10^-11 in order to round properly before truncating.

James Black
  • 41,583
  • 10
  • 86
  • 166
0

Multiply by 10^10 Rather than converting to an integer (which is 32 bit) it might be worth using an int64. An int 32 has a limit of approximatly 2 billion which when multipled out gives a range between +2.1 and -2.1 on your decimal value, an int64 has a much larger range that, when multiplied out gives you a range of approximatly +922,000,000 to -922,000,000 on the decimal value

http://msdn.microsoft.com/en-us/library/system.int32.aspx

http://msdn.microsoft.com/en-us/library/system.int64.aspx

zeocrash
  • 636
  • 2
  • 8
  • 31
-1

Maybe this works for you:

If Decimal.Round(yourDec1, 10, MidpointRounding.AwayFromZero) = Decimal.Round(yourDec2, 10, MidpointRounding.AwayFromZero) Then

Bobby

Bobby
  • 11,419
  • 5
  • 44
  • 69