Целочисленное деление с остатком в JavaScript? - PullRequest
810 голосов
/ 19 ноября 2010

Как в JavaScript получить:

  1. сколько раз одно целое число входит в другое?
  2. остаток?

Ответы [ 15 ]

1073 голосов
/ 19 ноября 2010

Для некоторого числа y и некоторого делителя x вычислить частное (quotient) и остаток (remainder) как:

var quotient = Math.floor(y/x);
var remainder = y % x;
341 голосов
/ 19 ноября 2010

Я не специалист по побитовым операторам, но вот еще один способ получить целое число:

var num = ~~(a / b);

Это будет работать правильно и для отрицательных чисел, тогда как Math.floor() будет округлять неправильнонаправление.

Это также кажется правильным:

var num = (a / b) >> 0;
181 голосов
/ 20 июня 2013

Я провел несколько тестов скорости на Firefox.

-100/3             // -33.33..., 0.3663 millisec
Math.floor(-100/3) // -34,       0.5016 millisec
~~(-100/3)         // -33,       0.3619 millisec
(-100/3>>0)        // -33,       0.3632 millisec
(-100/3|0)         // -33,       0.3856 millisec
(-100-(-100%3))/3  // -33,       0.3591 millisec

/* a=-100, b=3 */
a/b                // -33.33..., 0.4863 millisec
Math.floor(a/b)    // -34,       0.6019 millisec
~~(a/b)            // -33,       0.5148 millisec
(a/b>>0)           // -33,       0.5048 millisec
(a/b|0)            // -33,       0.5078 millisec
(a-(a%b))/b        // -33,       0.6649 millisec

Выше приведено 10 миллионов испытаний для каждого.

Вывод: Использование (a/b>>0) (или (~~(a/b)) или (a/b|0)) для повышения эффективности примерно на 20%.Также имейте в виду, что все они несовместимы с Math.floor, когда a/b<0 && a%b!=0.

114 голосов
/ 10 марта 2014

ES6 представляет новый метод Math.trunc.Это позволяет исправить ответ @ MarkElliot , чтобы он работал и для отрицательных чисел:

var div = Math.trunc(y/x);
var rem = y % x;

Обратите внимание, что методы Math имеют преимущество перед побитовыми операторами в том, что они работают с числами свыше 2 31 .

24 голосов
/ 14 февраля 2013
var remainder = x % y;
return (x - remainder) / y;
13 голосов
/ 13 апреля 2015

Вы можете использовать функцию parseInt, чтобы получить усеченный результат.

parseInt(a/b)

Чтобы получить остаток, используйте оператор мод:

a%b

parseInt есть некоторые подводные камни со строками, чтобы избежать использования параметра radix с основанием 10

parseInt("09", 10)

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

parseInt(100000000000000000000000000000000, 10) // 1e+32

В результате этого вызова будет получено значение 1.

6 голосов
/ 27 февраля 2014

JavaScript вычисляет прямо пол отрицательных чисел и остаток нецелых чисел, следуя математическим определениям для них.

FLOOR определяется как «наибольшее целое число, меньшее, чем параметр», таким образом:

  • положительные числа: FLOOR (X) = целая часть X;
  • отрицательные числа: FLOOR (X) = целая часть X минус 1 (потому что она должна быть МЕНЬШЕ, чемпараметр, т. е. более отрицательный!)

REMAINDER определяется как «остаток» деления (евклидова арифметика).Когда дивиденд не является целым числом, частное, как правило, также не является целым числом, то есть нет остатка, но если частное вынуждено быть целым числом (и это то, что происходит, когда кто-то пытается получить остаток или модульчисло с плавающей запятой), очевидно, будет нецелое «осталось», очевидно.

JavaScript вычисляет все как положено, поэтому программист должен быть осторожным, чтобы задавать правильные вопросы (и люди должны быть осторожныответить на то, что задают!) Первый вопрос Ярина был НЕ «что такое целочисленное деление X на Y», а «сколько раз одно целое число переходило в другое».Для положительных чисел ответ одинаков для обоих, но не для отрицательных, потому что целочисленное деление (делитель на делитель) будет на -1 меньше, чем число, которое (делитель) «переходит» в другое (делимое).Другими словами, FLOOR вернет правильный ответ для целочисленного деления отрицательного числа, но Ярин не спросил этого!

gammax ответил правильно, этот код работает так, как его попросил Ярин.С другой стороны, Самуил не прав, он, наверное, не делал математику, иначе он бы увидел, что это работает (кроме того, он не сказал, что было делителем его примера, но я надеюсь, что это было3):

Остаток = X% Y = -100% 3 = -1

GoesInto = (X - Остаток) / Y = (-100 - -1) / 3 = -99/ 3 = -33

Кстати, я тестировал код на Firefox 27.0.1, он работал как положено, с положительными и отрицательными числами, а также с нецелыми значениями, как для делимого, так и для делителя.Пример:

-100.34 / 3.57: GoesInto = -28, Remainder = -0.3800000000000079

Да, я заметил, что есть проблема с точностью, но у меня не было времени проверить ее(Я не знаю, если это проблема с Firefox, Windows 7 или с FPU моего процессора).Для вопроса Ярина, который включает только целые числа, код gammax работает отлично.

5 голосов
/ 01 ноября 2014

Math.floor(operation) возвращает округленное значение операции.

Пример 1 st вопрос:

var x = 5;
var y = 10.4;
var z = Math.floor(x + y);

console.log(z);

Консоль:

15

Пример 2 и вопрос:

var x = 14;
var y = 5;
var z = Math.floor(x%y);

console.log(x);

Консоль:

4

4 голосов
/ 20 мая 2017

Я обычно использую:

const quotient =  (a - a % b) / b;
const remainder = a % b;

Это, наверное, не самый элегантный, но работает.

2 голосов
/ 06 июля 2017

Комментарий Алекса Мура-Ниеми в качестве ответа:

Для Rubyists здесь от Google в поисках divmod, вы можете реализовать это так:

function divmod(x, y) {
  var div = Math.trunc(x/y);
  var rem = x % y;
  return [div, rem];
}

Результат:

// [2, 33]
...