-2

I am facing issue while comparing NSNumber. Below is my code:

 NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
        [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
        NSNumber *avgRating= [formatter numberFromString:attemptedQuizDetailsModel.avgRating];

        NSNumber *firstMinVal=[NSNumber numberWithFloat:0.6];
        NSNumber *firstMaxVal=[NSNumber numberWithFloat:1.5];
        NSNumber *secondMinVal=[NSNumber numberWithFloat:1.6];
        NSNumber *secondMaxVal=[NSNumber numberWithFloat:2.5];
        NSNumber *thirdMinVal=[NSNumber numberWithFloat:2.6];
        NSNumber *thirdMaxVal=[NSNumber numberWithFloat:3.5];
        NSNumber *fourthMinVal=[NSNumber numberWithFloat:3.6];
        NSNumber *fourthMaxVal=[NSNumber numberWithFloat:4.5];
        NSNumber *fifthMinVal=[NSNumber numberWithFloat:4.6];

if(avgRating >= firstMinVal && avgRating <= firstMaxVal){
} else if (avgRating>=fifthMinVal) {
}

if avgRating=4.6 and fifthMinVal=4.60,my comparison check is returning they are not equal. How to handle this type of comparison?

Martin
  • 846
  • 1
  • 9
  • 23
Vork
  • 746
  • 2
  • 12
  • 34
  • Possible duplicate of [How dangerous is it to compare floating point values?](https://stackoverflow.com/questions/10334688/how-dangerous-is-it-to-compare-floating-point-values) – Amin Negm-Awad Dec 22 '17 at 06:02

2 Answers2

1

You have two issues, one to do with objects and the other floating-point arithmetic.

First, the expression:

avgRating>=firstMinVal&&avgRating<=firstMaxVal

does not do what you think it does.

Every variable in this expression is of type NSNumber *, that is it is a pointer to an object containing a number, and the comparisons you are doing are between pointers – which is perfectly legal in (Objective-)C.

To compare two NSNumber objects you should use the compare: method, this returns an NSComparisonResult value indicating the order of the two values.

However you would be better off in your case simply sticking with double or float values throughout and not using object types.

In either case you must be careful about comparing floating-point values, comparing for equality (== or !=) may not give the results you expect due to limited precision and number base issues (a topic you should study if programming with floating-point). Ordering comparisons (>, <, >=, <=) are generally better, and you appear to be using only those, but may still give unexpected results for two "equal" values. To test for (in)equality it is usual to test for the absolute difference (abs(), fabs()) to be less than a small value – the magnitude of which depends on the application.

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86
0

This is a classic problem with comparing floating-point values; due to the way floating-point works, you can't reliably test them for equality.

What you should do instead is to compare the absolute value of the difference between the two floating-point values, and see if the difference is less than some suitably small value (say, 0.001). What value you use for the delta depends on what precision you need.

Charles Srstka
  • 16,665
  • 3
  • 34
  • 60