Home > Software design >  Contains within List of doubles
Contains within List of doubles

Time:04-05

Im using visual studio Immediate Window to check the content of my List. This is what I can see:

found_numbers
Count = 36
    [0]: 50,82
    [1]: 3358
    [2]: 954
    [3]: 5571
    [4]: 3142
    [5]: 700
    [6]: 322
    [7]: 402
    [8]: 1231
    [9]: 4118
    [10]: 4532
    [11]: 0
    [12]: 0
    [13]: 3101
    [14]: 18
    [15]: 0
    [16]: 0
    [17]: 8896
    [18]: 0
    [19]: 4,01
    [20]: 19,5
    [21]: 0,78
    [22]: 20,28
    [23]: 10
    [24]: 27,76
    [25]: 2,78
    [26]: 30,54
    [27]: 4648
    [28]: 508
    [29]: 1,51
    [30]: 4648
    [31]: 508
    [32]: 1,51
    [33]: 0,28
    [34]: 0,28
    [35]: 0,56

Then I check the value of my two variables

total1
50,82
total3
20,28

In the last step, I want to see if my list contains those values and this is my output:

found_numbers.Contains(total1)
false
found_numbers.Contains(total3)
true

Im really confused about this behaviour as the both numbers are into the the given list. Why could this be happening? Edit: both total1 and total3 are type double.

CodePudding user response:

When we do computation with double we get rounding errors, and that's why instead of 50,82 we actually have 50,82000000001 or 50,81999999998. All these values are usually represented being rounded as 50,82 and we have strange found_numbers.Contains(total1) == false. To get exact double value use R format;

found_numbers[0].ToString("R")
total1.ToString("R")

try these representations and you'll see the diffrence. If you want to get rid of rounding problems you can:

  1. Switch from double to decimal (esp. if values have fixed decimal point, e.g. if values are currencies)
  2. Use tolerance when comparing:
//TODO: put the right value here
double tolerance = 1e-8;

bool found = found_numbers.Any(item => Math.Abs(item - total1) <= tolerance);
  • Related