В JavaScript, как получить:
- Сколько раз одно целое число переходит в другое?
- Остаток?
В JavaScript, как получить:
Для некоторого числа y
и некоторого делителя x
вычислить частное (quotient
) и остаток (remainder
) как:
var quotient = Math.floor(y/x);
var remainder = y % x;
3.5 % 2
оценивается как 1,5. Не забудьте обработать (parseInt, floor и т. Д.) По мере необходимости
- person ; 19.11.2010
floor
и %
несовместимо. Либо используйте trunc
вместо floor
(тем самым разрешая отрицательные остатки), либо используйте вычитание, чтобы получить остаток (rem = y - div * x
).
- person Mark Reed; 17.02.2016
Math.floor()
здесь только в том случае, если данное число положительно. для получения дополнительных объяснений см. здесь. Обычно parseInt()
- лучший выбор для получения целой части числа или строки.
- person tnga; 04.04.2016
rem
, вы можете получить частное div
быстрее без покрытия: (y - rem) / x
. 2. Между прочим, операцию по модулю в соответствии с рекомендуемым определением Дональда Кнута (знак-совпадение-делитель, а не остаток, то есть евклидов модуль, ни знак-совпадение-делимое в JavaScript) - это то, что мы можем закодировать в JavaScript как function mod (a, n) { return a % n + (Math.sign(a) !== Math.sign(n) ? n : 0); }
.
- person Aaron Mansheim; 06.02.2017
quotient * divisor + remainder = dividend
истинным, частное должно быть минимальным.
- person Mark Reed; 22.08.2017
-9 % 2
это -1
вместо 1
.
- person ramwin; 02.01.2019
Я не разбираюсь в побитовых операторах, но вот еще один способ получить целое число:
var num = ~~(a / b);
Это будет правильно работать и для отрицательных чисел, в то время как Math.floor()
будет округляться в неправильном направлении.
Это тоже кажется правильным:
var num = (a / b) >> 0;
a/b | 0
- person BlueRaja - Danny Pflughoeft; 26.03.2011
~~int
, int | 0
и int >> 0
не изменяют начальный аргумент, но заставляют интерпретатор передавать оператору неотъемлемую часть.
- person Aleksei Zabrodskii; 15.07.2012
floor
вряд ли поворачивает в неправильном направлении, учитывая его название - просто не то направление, которого обычно хотят люди!
- person Mark K Cowan; 19.12.2013
a = 12447132275286670000; b = 128
Math.floor(a/b)
- ›97243220900677100
и ~~(a/b)
-› -1231452688
.
- person Mirek Rusin; 26.03.2014
~~(5/2) --> 2
, как и (5/2)>>0 --> 2
, но ~~(5/2) + 1 --> 3
, а ~~(5/2)>>0 + 1 --> 1
. ~~
- хороший выбор, потому что приоритет более уместен.
- person timkay; 29.05.2014
>>0
, поэтому emscripten и asm.js используют |0
- person technosaurus; 31.07.2014
Math.floor
, когда числа превышают 53 бита ... Это просто неотъемлемые ограничения, присутствующие повсюду. Если вы хотите сделать это для произвольно больших чисел, вам понадобится библиотека bigint / bignumber.
- person Stijn de Witt; 27.11.2015
Math.floor
округляет отрицательное частное в неправильном, а скорее в другом направлении. Math.floor(-3 / 10) === -1
тогда будет соответствовать делению по полу (округляет вниз), тогда как ~~(-3 / 10) === 0
соответствует усеченному делению (округляет до нуля ). См. Wiki: операция по модулю.
- person mucaho; 18.03.2016
Math.floor
или новый Math.trunc
ES6 (Edge 12+)
- person fregante; 30.05.2016
| 0
для усечения, особенно из-за его использования в asm.js, поэтому вы не можете точно сказать, что он запутывает код, потому что его значение уже широко известно.
- person Shien; 24.09.2016
|0
. Также не имеет значения, что asm.js использует определенный стиль, поскольку он предназначен не для записи / чтения людьми, а для транспиляторов и браузеров.
- person fregante; 25.09.2016
~~
или | 0
еще не существовали, у кого-то могло возникнуть искушение добавить их. Как сказал Джоэл, старый код не ржавеет . Не используйте существующие полезные соглашения просто потому, что они старые. Это хороший.
- person ruffin; 24.03.2017
TypeError: unsupported operand type(s) for |: 'float' and 'int'
- person Serge Stroobandt; 30.03.2021
Я сделал несколько тестов скорости в 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
.
Math.floor
и неизвестно сколько других функциях API или узнать об операторе ~
(побитовое-не) и о том, как побитовые операции работают в JS, а затем понять i > эффект двойной тильды?
- person Stijn de Witt; 27.11.2015
Math.floor
лучше. И даже если нет, этот можно гуглить.
- person mik01aj; 28.11.2015
|0
, поскольку это выглядит как нерабочий… «Ага, это преобразование в int», будучи четким и прямым ответом, заставляет меня быть поклонником этого выбора
- person JamesTheAwesomeDude; 22.09.2020
TypeError: unsupported operand type(s) for |: 'float' and 'int'
- person Serge Stroobandt; 30.03.2021
Math.floor(a/b)
побитовую операцию, кажется достаточно простым.
- person Michael Scheper; 21.06.2021
ES6 представляет новый метод Math.trunc
. Это позволяет исправить ответ @ MarkElliot, чтобы он работал и для отрицательных чисел:
var div = Math.trunc(y/x);
var rem = y % x;
Обратите внимание, что Math
методы имеют преимущество перед побитовыми операторами в том, что они работают с числами, превышающими 2 31.
18014398509481984 == 18014398509481985
.
- person Oriol; 03.02.2015
18014398509481984 / 5
это 3602879701896396.8
. Однако его нельзя сохранить, поэтому он преобразуется в 3602879701896397
. И тогда Math.trunc(3602879701896397)
это 3602879701896397
.
- person Oriol; 03.02.2015
Math.trunc
, если он у вас есть, или Math.floor
в противном случае (с поправкой на отрицательные числа). Нужно поддерживать еще большие числа? Используйте какую-нибудь большую библиотеку чисел.
- person Stijn de Witt; 27.11.2015
divmod
можно реализовать как таковое: function divmod(x, y) { var div = Math.trunc(x/y); var rem = x % y; return [div, rem]; }
- person Alex Moore-Niemi; 25.11.2016
Обычно я использую:
const quotient = (a - a % b) / b;
const remainder = a % b;
Наверное, не самый элегантный, но работает.
Вы можете использовать функцию parseInt
, чтобы получить усеченный результат.
parseInt(a/b)
Чтобы получить остаток, используйте оператор мода:
a%b
parseInt имеет некоторые подводные камни со строками, чтобы избежать использования параметра radix с основанием 10
parseInt("09", 10)
В некоторых случаях строковое представление числа может быть научной записью, в этом случае parseInt выдаст неверный результат.
parseInt(100000000000000000000000000000000, 10) // 1e+32
Результатом этого вызова будет 1.
parseInt
по возможности следует избегать. Вот предупреждение Дугласа Крокфорда: если первый символ строки равен 0, тогда строка оценивается по базе 8, а не по базе 10. В базе 8, 8 и 9 не являются цифрами, поэтому parseInt (08) и parseInt (09) производят 0 в качестве своего результата. Эта ошибка вызывает проблемы в программах, анализирующих дату и время. К счастью, parseInt может принимать параметр radix, так что parseInt (08, 10) дает 8. Я рекомендую всегда указывать параметр radix. archive.oreilly.com/pub/ а / javascript / выдержки /
- person Powers; 02.11.2015
parseInt
следует избегать; просто нужно знать о некоторых подводных камнях. Вы должны знать об этом и быть готовым к тому, чтобы справиться с этим.
- person None; 22.12.2015
parseInt
с числовым аргументом. parseInt
должен анализировать частично числовые строки, а не усекать числа.
- person Oriol; 16.06.2016
Math.floor(operation)
возвращает округленное в меньшую сторону значение операции.
Пример 1 st вопроса:
var x = 5;
var y = 10.4;
var z = Math.floor(x + y);
console.log(z);
Консоль:
15
Пример 2 nd вопроса:
var x = 14;
var y = 5;
var z = Math.floor(x%y);
console.log(x);
Консоль:
4
JavaScript вычисляет нижний предел отрицательных чисел и остаток нецелых чисел, следуя математическим определениям для них.
FLOOR определяется как «наибольшее целое число, меньшее, чем параметр», таким образом:
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, остаток = -0,3800000000000079
Да, я заметил, там есть проблема с точностью, но у меня не было времени проверить это (я не знаю, проблема ли это в Firefox, Windows 7 или с FPU моего процессора). Однако на вопрос Ярина, который включает только целые числа, код gammax работает отлично.
Ответ Алекса Мур-Ниеми в качестве ответа:
Для рубистов из Google в поисках divmod
вы можете реализовать это как таковое:
function divmod(x, y) {
var div = Math.trunc(x/y);
var rem = x % y;
return [div, rem];
}
Результат:
// [2, 33]
divmod
использует деление по полу (Math.floor
), которое отличается от усеченного деления (Math.trunc
), когда задействованы отрицательные числа. Это касается пакета NPM divmod
, Ruby divmod
, SWI-Prolog divmod
и, вероятно, многие другие реализации тоже.
- person Palec; 07.07.2017
divmod
существует, потому что он выполняется в два раза быстрее, чем вычисление двух операций по отдельности. Предоставление такой функции без этого преимущества в производительности может сбивать с толку.
- person Palec; 07.07.2017
const idivmod = (a, b) => [a/b |0, a%b];
есть также предложение, работающее над этим Модуль и дополнительная целочисленная математика
Если вы просто делите степень двойки, вы можете использовать побитовые операторы:
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];
}
(Первое - частное, второе - остаток)
function divideByPowerOf2(num, exponent) { return [num >> exponent, num & ((1 << exponent) - 1)]; }
.
- person Palec; 13.09.2017
Подсчитать количество страниц можно за один шаг: Math.ceil (x / y)
Вы можете использовать тернарность, чтобы решить, как обрабатывать положительные и отрицательные целые числа.
var myInt = (y > 0) ? Math.floor(y/x) : Math.floor(y/x) + 1
Если число положительное, все в порядке. Если число отрицательное, оно добавит 1 из-за того, как Math.floor обрабатывает негативы.
Это всегда будет усекаться до нуля. Не уверен, что уже слишком поздно, но вот оно:
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 представляется как число с плавающей запятой и поэтому теряет точность), вам нужно проделать некоторую уловку.
Это особенно важно для проверки многих контрольных цифр, которые присутствуют во многих случаях нашей повседневной жизни (номера банковских счетов, кредитные карты, ...)
В первую очередь вам нужен ваш номер в виде строки (иначе вы уже потеряли точность, а остаток не имеет смысла).
str = '123456789123456789123456789'
Теперь вам нужно разделить вашу строку на более мелкие части, достаточно маленькие, чтобы объединение любого остатка и части строки могло уместиться в 9 цифрах.
digits = 9 - String(divisor).length
Подготовьте регулярное выражение для разделения строки
splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g')
Например, если digits
равно 7, регулярное выражение будет
/.{1,7}(?=(.{7})+$)/g
Он соответствует непустой подстроке максимальной длины 7, за которой следует ((?=...)
- положительный просмотр вперед) количество символов, кратное 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);
}
Вот способ сделать это. (Лично я бы не стал делать это таким образом, но подумал, что это интересный способ сделать это для примера)
function intDivide(numerator, denominator) {
return parseInt((numerator/denominator).toString().split(".")[0]);
}
let x = intDivide(4,5);
let y = intDivide(5,5);
let z = intDivide(6,5);
console.log(x);
console.log(y);
console.log(z);
Math.trunc
:). Я проверил 100,3; -100,3; 100, -3 и -100, -3. Конечно, с момента вашего комментария прошло много времени, и все изменилось.
- person Marjan Venema; 12.07.2018