Целочисленное деление с остатком в JavaScript?


в JavaScript, как мне получить:

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

15 ответов:

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

var quotient = Math.floor(y/x);
var remainder = y % x;

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

var num = ~~(a / b);

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

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

var num = (a / b) >> 0;

Я сделал некоторые тесты скорости на 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.

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

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

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

var remainder = x % y;
return (x - remainder) / y;

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

parseInt(a/b)

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

a%b

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

parseInt("09", 10)

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

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

этот вызов приведет к 1 в результате.

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

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

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

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

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

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, Остаток = -0.3800000000000079

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

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

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

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

console.log(z);

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

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

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

результат:

// [2, 33]

Если вы просто делите с степенями два, вы можете использовать побитовые операторы:

export function divideBy2(num) {
  return [num >> 1, num & 1];
}

export function divideBy4(num) {
  return [num >> 2, num & 3];
}

export function divideBy8(num) {
  return [num >> 3, num & 7];
}

(первый фактор, второй остаток)

расчет количества страниц может быть сделано в один шаг: Математика.ceil (x/y)

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

var myInt = (y > 0) ? Math.floor(y/x) : Math.floor(y/x) + 1

если число положительное, все в порядке. Если число отрицательное, оно добавит 1 из-за, как математика.пол обрабатывает негативы.

Я обычно использую (a - a % b) / b. Это, наверное, не самый элегантный, но он работает.

это всегда будет усекаться к нулю. Не уверен, что это слишком поздно, но вот он идет:

function intdiv(dividend, divisor) { 
    divisor = divisor - divisor % 1;
    if (divisor == 0) throw new Error("division by zero");
    dividend = dividend - dividend % 1;
    var rem = dividend % divisor;
    return { 
        remainder: rem, 
        quotient: (dividend - rem) / divisor
    };
}

Если вам нужно вычислить остаток для очень больших целых чисел, которые среда выполнения JS не может представить как таковые (любое целое число больше 2^32 представлено как float и поэтому оно теряет точность), вам нужно сделать некоторый трюк.

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

прежде всего вам нужен ваш номер в виде строки (в противном случае вы уже потеряли точность и остальное не имеет смысла).

str = '123456789123456789123456789'

теперь вам нужно разделить строку на более мелкие части, достаточно маленькие, чтобы конкатенация любого остатка и кусок строки могли поместиться в 9 цифр.

digits = 9 - String(divisor).length

подготовьте регулярное выражение для разделения строки

splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g')

например, если digits это 7, регулярное выражение

/.{1,7}(?=(.{7})+$)/g

он соответствует непустой подстроке максимальной длины 7, которая следует ((?=...) является положительным lookahead) по количеству символов, кратных 7. 'G' - это заставить выражение проходить через всю строку, не останавливаясь на первом совпадении.

теперь преобразуйте каждую часть в целое число и вычислите остатки по reduce (добавляя назад предыдущий остаток - или 0-умноженный на правильную степень 10):

reducer = (rem, piece) => (rem * Math.pow(10, digits) + piece) % divisor

это будет работать из-за "вычитание" алгоритм остаток:

n mod d = (n - kd) mod d

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

финальный код будет выглядеть так:

function remainder(num, div) {
  const digits = 9 - String(div).length;
  const splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g');
  const mult = Math.pow(10, digits);
  const reducer = (rem, piece) => (rem * mult + piece) % div;

  return str.match(splitter).map(Number).reduce(reducer, 0);
}