2009-11-04 2 views
2

Возможные Дубликаты:
Strange problem comparing floats in objective-C
Is JavaScript’s math broken?
1.265 * 10000 = 126499.99999999999 ?????Как работать с десятичной проблемой в JavaScript?

После просмотра this я обнаружил, что в JavaScript:

0.1 + 0.2 === 0.3 

оценивается как ложное.

Есть ли способ обойти это?

+3

http://docs.sun.com/source/806-3568/ncg_goldberg.html – nlucaroni

+1

Это было предложено много раз: http://stackoverflow.com/search?q=javascript+floating+point –

+0

Извините за повторение. – camomileCase

ответ

2

Как насчет

function isEqual(a, b) 
{ 
    var epsilon = 0.01; // tunable 
    return Math.abs(a - b) < epsilon; 
} 
+0

@alex: Я не понимаю, почему вы изменили обрезание с '0.01' до' 0.0'. Эта функция теперь всегда возвращает 'false', даже если два значения * полностью * идентичны. Нет? – ruakh

+0

@ruakh Меня тоже, возможно, это было ошибкой. Я исправлю это :) – alex

1

Вы всегда должны сравнивать числа с плавающей запятой, используя константу (обычно называемую epsilon), чтобы определить, может ли два числа отличаться считаться «равными».

1

Использования фиксированной точки математики (читайте: целые числа), чтобы сделать математику, где вы заботитесь о том, что такой точности. В противном случае напишите функцию, которая сравнивает ваши числа в диапазоне, который вы можете принять как «достаточно близко» к равному.

2

Это проблема, присущая двоичным числам, которые попадают все основные языки программирования.

Преобразование десятичного числа .1 (1/10) в двоичный файл вручную - вы обнаружите, что у него есть повторяющаяся мантисса и не может быть точно представлена. Как попытка представить 1/3 как десятичную.

+0

Проблема заключается в двоичной с плавающей запятой, а не в двоичных числах вообще. Там есть десятичные библиотеки с плавающей запятой (хотя и не уверены в JS), которые избегают этой проблемы. – ScottJ

+1

Нет, это проблема с двоичными числами. Вы не можете представлять .1 как естественное двоичное число.«десятичные» библиотеки обходятся, представляя десятичные цифры или используя десятичные числа с фиксированной запятой. –

+0

Хорошо, правда. Я должен был сказать, что эта проблема не влияет на двоичные целые числа. – ScottJ

1

Просто идея. Умножьте 10000 (или несколько одинаково большое число, если оно больше вашего максимального количества десятичных знаков) до всех ваших значений, прежде чем сравнивать их, поэтому они будут целыми числами.

function padFloat(val) { 
    return val * 10000; 
} 

padFloat(0.1) + padFloat(0.2) === padFloat(0.3); 
1

Вы можете конечно умножить каждое число как

10 * 0.1 + 10 * 0.2 === 10 * 0.3 

, который оценивает к истине.

5

Лучший и единственный ответ, который я нашел, который дает точные результаты, заключается в использовании библиотеки Decimal. Класс Java BigDecimal портирован на javascript, см. Мой ответ в this SO post.

Примечание: Значения масштабирования будут «обрабатывать» проблему, но не «вылечат» ее.

 Смежные вопросы

  • Нет связанных вопросов^_^