﻿# V7036\. Suspicious precise comparison\. Consider using a comparison with defined precision\.

Анализатор обнаружил фрагмент кода, где для сравнения чисел с плавающей точкой используются операторы \=\=, \=\=\=, \!\=, \!\=\=\. Такой код может содержать потенциальную ошибку\. 

Рассмотрим пример:

```cpp
let result = x * y;
if (result === 0.1) { // <= 
  ....
}
```

Условие `result === 0.1` практически никогда не будет истинным\. Это связано с тем, что согласно стандарту [IEEE 754](https://ru.wikipedia.org/wiki/IEEE_754), JavaScript представляет число `0.1` лишь как максимально приближенное к нему значение: `0.1000000000000000055511151231257827021181583404541015625`\. Вероятность получить точно такой же результат после арифметических операций крайне мала\. 

Исправить ошибку можно, сравнивая разность значений с заданной точностью:

```cpp
let result = x * y;
if (Math.abs(result - 0.1) < Number.EPSILON) { // <= 
  ....
}
```

Данный способ проверки подходит для чисел малых порядков \(подробнее об этой проблеме можно прочитать в официальной документации: [Number\.EPSILON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON)\)\. Более универсальный вариант проверки — сравнение и абсолютной, и относительной погрешностей двух чисел:

```cpp
function nearlyEqual(a, b,
                     relEpsilon = 4 * Number.EPSILON,
                     absEpsilon = Number.EPSILON
) {
  if (a === b) {
    return true;
  }

  if (Number.isNaN(a) || Number.isNaN(b)) {
    return false;
  }

  let difference = Math.abs(a - b);

  if (difference <= absEpsilon) {
    return true;
  }
  
  let maxAbsoluteValue = Math.max(Math.abs(a), Math.abs(b)); 
  return difference / maxAbsoluteValue <= relEpsilon;
}

let result = x * y;
if (nearlyEqual(result, 0.1)) { 
  ....
}
```