2013-03-13 3 views
0

предупреждение (5.30/0.1);раздел javascript, дающий неправильный ответ?

Это дает 52.99999999999999, но должно быть 53. Кто-нибудь может сказать, как и почему?

Я хочу найти, что число делится на заданное число. Обратите внимание, что одним из чисел может быть float.

+6

[Что каждый ученый должен знать о арифметики с плавающей запятой] (HTTP: // docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – C5H8NNaO4

ответ

-1

Чтобы узнать, соответствует ли число x числом yx % y (modulo). Если результат равен 0, он отлично делится, а другой нет.

+3

К сожалению, это также вернет значение, в отличие от '0' в этом случае. – insertusernamehere

-1

Вы можете получить это по следующему: var num = (5.30/0.1); предупреждение (num.toFixed (2));

это даст вам 53.00.

+0

В вопросе говорится: «Я хочу найти, что число делится на заданное число *», предположительно это означает «точно делимое». Если вы отбросите все после десятичной точки, то каждый отрицательный результат будет выдан как ложноположительный. – Quentin

+0

@Quentin См. В первой строке: Это дает 52.99999999999999, но должно быть 53. Кто-нибудь может сказать, как и почему? –

+0

- См. Вторую строку. «Я хочу найти, что число делится на заданное число. *». Ваш ответ касается только первой строки без учета контекста. Контекст важен. – Quentin

9

По той же причине, что

0.1 * 0.2 //0.020000000000000004 

Некоторые десятичные числа не могут быть представлены в IEEE 754, математического представления используется JavaScript. Если вы хотите выполнить арифметику с этими числами в своем вопросе, было бы лучше размножить их, пока они не станут целыми числами, а затем разделите их.

7

Масштабировать цифры, чтобы они стали целыми. Тогда модуль результата.

alert((5.30*10) % (0.1*10)); 
+0

Это не всегда работает, ниже: (1.5876 * 10000)% (0,0001 * 10000) результат 0.999999999998 – Trans

+0

@Trans but '(1.5876 * 100000)% (0.0001 * 100000)' does – DickieBoy

0

Теперь, когда вы прочитали статью, которую я прокомментировал, вы должны знать корень своей проблемы. Вы можете частично обойти, что путем масштабирования вы поплавки ...

Тогда просто написать функцию, которая:

  • Если его поплавок
    • Масштабные Числа
  • Вернуть булево представление делимости числа

function isDivisable(n, d) { 
    var ndI = 1 + "".indexOf.call(n, "."); //Index of the Number's Dot 
    var ddI = 1 + "".indexOf.call(d, "."); // Index of the Divisors Dot 
    if (ndI || ddI) { // IF its a float 
     var l = Math.max(("" + n).length - ndI, ("" + d).length - ddI); //Longest Decimal Part 
     var tmpN = (n * Math.pow(10, l)); //scale the float 
     var tmpD = (d * Math.pow(10, l)); 
     return !~((tmpN % tmpD) - 1); //Substract one of the modulo result, apply a bitwise NOT and cast a boolean. 
    } 
    return !~((n % d) - 1); // If it isnt a decimal, return the result 
} 
console.log(isDivisable(5.30, 0.1));//true 

Херес JSBin

Однако ...

Как Целые сохраняются с 64-битной точностью, максимальная точность лжет (2^53), и вы скоро превысит максимальную точность при масштабируя большие числа.

Так что это может быть хорошей идеей, чтобы получить какую-то BigInteger библиотеки для JavaScript если вы хотите проверить поплавки делимости

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