1336

In JavaScript, how do I get:

  1. The whole number of times a given integer goes into another?
  2. The remainder?
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Yarin
  • 173,523
  • 149
  • 402
  • 512

19 Answers19

1791

For some number y and some divisor x compute the quotient (quotient)[1] and remainder (remainder) as:

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

Example:

const quotient = Math.floor(13/3); // => 4 => the times 3 fits into 13  
const remainder = 13 % 3;          // => 1

[1] The integer number resulting from the division of one number by another

Kostas Minaidis
  • 4,681
  • 3
  • 17
  • 25
Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
  • 107
    % works on floats in JavaScript (this differs from many other languages), which is perhaps not desired: `3.5 % 2` evaluates to 1.5. Make sure to handle (parseInt, floor, etc.) as required –  Nov 19 '10 at 19:09
  • 22
    The integral part of -4.5 in mathematics is -5, as -5 is the "highest possible integral number that is still lower than -4.5". – Toughy Dec 03 '14 at 13:40
  • 27
    However, whatever you decide to do about negative numbers, it should be consistent across the quotient and the remainder. Using `floor` and `%` together is not consistent in that way. Either use `trunc` instead of `floor` (thereby permitting negative remainders) or use subtraction to get the remainder (`rem = y - div * x`). – Mark Reed Feb 17 '16 at 19:31
  • usage of `Math.floor()` here is just for the case that given number are positive. [look at this for more explaination](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Math/floor). Normally `parseInt()` is a better choose to get integer part of number or string. – tnga Apr 04 '16 at 09:34
  • 13
    1. If you're going to compute the remainder `rem` anyway, you can get the quotient `div` faster without flooring: `(y - rem) / x`. 2. By the way the modulo operation by Donald Knuth's recommended definition (sign-matches-divisor, not the remainder i.e. Euclidean modulus, nor the JavaScript sign-matches-dividend) is what we can code in JavaScript as `function mod (a, n) { return a % n + (Math.sign(a) !== Math.sign(n) ? n : 0); }`. – Aaron Mansheim Feb 06 '17 at 17:25
  • @MarkReed, Toughy: Given the description in the question, I don't understand how 2 could go into -9 a total of -5 times. Could you please explain? – spanky Aug 21 '17 at 20:59
  • 2
    -9 / 2 = -4.5. You then take the floor of -4.5, which is -5. Remember that -5 is less than -4.5, and the floor operation is defined as the largest integer less than a given value. – Mark Reed Aug 21 '17 at 22:57
  • 1
    Note that in general, having -3 modulo 5 be 2 is instead of -3 may be surprising, but it is mathematically more useful as it avoids any discontinuity around 0; any integer modulo a positive n is always in the range [0,n-1], whether the starting integer is positive or negative. But to go along with that definition and keep the identity `quotient * divisor + remainder = dividend` true, the quotient has to be the floor. – Mark Reed Aug 21 '17 at 22:59
  • 1
    Attention, this didn't work on negative number because `-9 % 2` is `-1` instead of `1`. – ramwin Jan 02 '19 at 10:36
  • @user166390 all numbers are floats in javascript – ICW Mar 20 '21 at 21:02
  • @martinho, parseInt() is slow and may even produce incorrect results. The reason is it stringifies the parameter and parses it again as a number. When the result of stringification is in scientific notation, the result is usually wrong. https://gideonpyzer.dev/blog/2017/06/06/js-tip-use-parseint-for-strings-not-for-numbers/ Also, you broke the code in the answer. I rolled back your edit. – Palec Dec 29 '21 at 14:16
492

I'm no expert in bitwise operators, but here's another way to get the whole number:

var num = ~~(a / b);

This will work properly for negative numbers as well, while Math.floor() will round in the wrong direction.

This seems correct as well:

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

Note: Only use ~~ as a substitution for Math.trunc() when you are confident that the range of input falls within the range of 32-bit integers.

Damien
  • 1,140
  • 15
  • 22
user113716
  • 318,772
  • 63
  • 451
  • 440
  • 105
    Another one, whose purpose I just spent the last 20 minutes trying to figure out, is apparently `a/b | 0` – BlueRaja - Danny Pflughoeft Mar 25 '11 at 22:42
  • 26
    @user113716 @BlueRaja Bitwise operations makes sense only on integer-types and JS (of course) knows that. `~~int`, `int | 0` and `int >> 0` doesn't modify initial argument, but make interpreter pass integral part to operator. – Aleksei Zabrodskii Jul 15 '12 at 15:15
  • 3
    Just in case anybody was wondering which was fastest: http://jsperf.com/integer-division-math-floor-a-b-vs-a-b (Spoiler results looks inconclusive). – jonasfj Dec 24 '12 at 11:31
  • 19
    `floor` hardly rounds in the wrong direction, given its name - just not the direction that people generally want though! – Mark K Cowan Dec 19 '13 at 00:34
  • 36
    That's a buu buu. `a = 12447132275286670000; b = 128` `Math.floor(a/b)` -> `97243220900677100` and `~~(a/b)` -> `-1231452688`. – Mirek Rusin Mar 26 '14 at 13:03
  • 10
    Be careful with precedence. `~~(5/2) --> 2` as does `(5/2)>>0 --> 2`, but `~~(5/2) + 1 --> 3`, while `~~(5/2)>>0 + 1 --> 1`. `~~` is a good choice because the precedence is more appropriate. – timkay May 29 '14 at 03:36
  • the unwanted behavior of `>>0` is why emscripten and asm.js use `|0` – technosaurus Jul 31 '14 at 18:55
  • 7
    just to clarify - these actually work because they are no-ops and all js bitwise operations convert to 32 bit ints – JonnyRaa Sep 17 '14 at 13:37
  • 7
    Agreeing with Jonny Leeds. In fact, while this solution deserves to be mentioned, I would reject it as the best coding practice. The answer by Mark Elliot uses a function that is provided for the purpose. This answer relies on a behavior which is neither guaranteed or intended by the implementation of bitwise operations. – Mark Goldfain Nov 22 '14 at 17:31
  • 3
    Answers are buubuus ~~( 2147483648/1) = -2147483648 (2147483648/1) >> 0 = -2147483648 – Chihung Yu May 07 '15 at 02:58
  • great in a context where you don't have Math library ( in my case, in templates ) – vincent Aug 30 '15 at 21:56
  • This answer works for numbers that fit inside the range of a signed integer, as Javascript only uses the least significant 32 bits for bitwise operations. However the OP asked about integer operations and ints are actually 32bit signed numbers in most languages (JS does not actually have ints) so I think that is not a problem. Yes it will fail for very large numbers, but so will `Math.floor` when numbers go beyond 53 bits... It's just the inherent limitations present all over the place. If you want to do this for arbitrarily large numbers, you need some bigint / bignumber library. – Stijn de Witt Nov 27 '15 at 20:49
  • I wouldn't say that `Math.floor` rounds the negative quotient in the _wrong_, but rather in a _different_ direction. `Math.floor(-3 / 10) === -1` would then correspond to _floored division_ (rounds _"downwards"_), whereas `~~(-3 / 10) === 0` corresponds to _truncated division_ (rounds _"towards zero"_). See [Wiki: Modulo operation](https://en.wikipedia.org/wiki/Modulo_operation). – mucaho Mar 18 '16 at 18:05
  • 2
    This is essentially code obfuscation. Don't do this to be clever, use the slightly longer but more readable `Math.floor` or the new `Math.trunc` of ES6 (Edge 12+) – fregante May 30 '16 at 18:26
  • 2
    @bfred.it Most developers already accept the use of `| 0` to truncate, particularly due to its use in asm.js, so you can't exactly say it obfuscates the code, because its meaning is already widely known. – Shien Sep 24 '16 at 09:04
  • I was commenting on the answer and that does not mention `|0`. Also it's irrelevant that asm.js uses a specific style since it's not meant to be written/read by humans but by transpilers and browsers – fregante Sep 25 '16 at 03:00
  • 5
    @bfred.it Idk. Ternaries look weird the first time you see them them. [Null conditionals](http://stackoverflow.com/a/28352116/1028230) also look really weird at first. Nobody says not to use them because they seem clever; instead, they're new lang additions *that devs are expected to learn*. If `~~` or `| 0` didn't already helpfully exist, someone might've been tempted to add them. As [Joel has said](https://www.joelonsoftware.com/2000/11/20/netscape-goes-bonkers/), "Old code doesn’t rust". Don't not use helpful existing conventions simply because they're old. This is A Good One. – ruffin Mar 24 '17 at 13:12
  • @BlueRaja-DannyPflughoeft By employing a [bitwise OR on a float](https://stackoverflow.com/q/6194950/2192488) in this manner, you are basically banking on the immaturity of JavaScript. Python3 would raise the error `TypeError: unsupported operand type(s) for |: 'float' and 'int'` – Serge Stroobandt Mar 30 '21 at 15:14
  • 1
    But, beware that bitwise ops are only for 32 bit integers. – 0zkr PM Jun 23 '21 at 01:38
  • At the time of this comment, `Math.trunc()` is recommended. [As the docs point out](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc#using_bitwise_no-ops_to_truncate_numbers) using bitwise no-ops to truncate will produce bugs when used with values that don't fit within the range of 32-bits. – Unknown Feb 28 '23 at 21:09
300

I did some speed tests on 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

The above is based on 10 million trials for each.

Conclusion: Use (a/b>>0) (or (~~(a/b)) or (a/b|0)) to achieve about 20% gain in efficiency. Also keep in mind that they are all inconsistent with Math.floor, when a/b<0 && a%b!=0.

KalEl
  • 8,978
  • 13
  • 47
  • 56
  • 2
    I find Math.floor() has more stable performance than others do. it is less up-and-down – Henry Leu Sep 12 '13 at 10:53
  • 93
    Note that optimizing integer division for speed would make sense only if you're doing it *a lot*. In any other case I would recommend choosing the simplest one (whichever seems simplest to you and your coworkers). – mik01aj Jan 08 '14 at 14:49
  • 11
    @m01 totally agree - there's way too much of a focus on stuff like this online – JonnyRaa Sep 17 '14 at 13:32
  • 7
    @m01 But which is harder: learning about `Math.floor` and the who-knows-how-many other API functions, or learning about the `~` (bitwise-not) operator and how bitwise operations work in JS and then *understanding* the effect of double tilde? – Stijn de Witt Nov 27 '15 at 20:53
  • 27
    Well, if your coworkers aren't programming chips in assembler, they'll likely understand `Math.floor` better. And even if not, this one is googleable. – mik01aj Nov 28 '15 at 14:38
  • 1
    | 0: 2582.521ms ~~: 2631.974ms Math.floor: 2382.893ms. I would encourage you to run the tests yourself, https://plnkr.co/edit/9g0IXjpavR2t2d2L1DC0 – Peheje Oct 15 '16 at 15:23
  • 2
    @JonnyLeeds I came here looking for integer division in Javascript, which isn't a niche requirement. – Barracoder Aug 09 '17 at 14:50
  • 2
    @MarkGreen yes but just wanting to do that doesn't mean you should write it in a weird form just because it happens to be fastest, without good reason - code clarity in general should normally be your first concern. Also these tests might be completely meaningless after language changes and across different browsers - you'd need to profile to find out what is slow in your application regardless. It's unlikely to be your integer division method unless you've already optimised ever single other thing! – JonnyRaa Sep 20 '17 at 12:07
  • Beware, all the bitwise operations are working only with 32-bit numbers – k06a Jun 17 '20 at 21:46
  • In terms of readability, I just had someone ask what `|0` is doing, since it looks like a non-op… “Yep—it's a cast-to-int” being a clear and direct answer leads me to be a fan of this choice – JamesTheAwesomeDude Sep 22 '20 at 07:11
  • @JonnyRaa Good code is fast and easy to understand. Generally speaking, optimizing JavaScript runtimes like V8 do better if you encapsulate performance sensitive code in a function because that means they only have to evaluate the code inside that function to optimize it. You can write a very well documented "fast_integer_divide" function with bitwise hacks and then everywhere else in the code you see "fast_integer_divide" which is even clearer than Math.floor and MUCH faster (5x) in my tests. Code legibility is very important but please do not encourage people to sacrifice performance.. – Sam Claus Dec 04 '20 at 17:24
  • Math.floor still doesn't work. Thank you for the work around. – Display name Feb 12 '21 at 00:58
  • 3
    This is a performance comparison of integer division methods, not an answer to the question. – mikemaccana Mar 02 '21 at 14:09
  • By employing a [bitwise operations on a float](https://stackoverflow.com/q/6194950/2192488) in this manner, you are basically banking on the immaturity of JavaScript. Python3 would raise the error `TypeError: unsupported operand type(s) for |: 'float' and 'int'` – Serge Stroobandt Mar 30 '21 at 15:15
  • For starters, if fractions of milliseconds make a difference to your application, JavaScript doesn't seem the best language choice. But if you have a case where performance is really more important than readability, and you're stuck with JS, be aware that performance isn't uniform across all platforms. I'd be surprised if this particular optimisation would be worth a development team's resources, but if it was, an interpreter automatically coverting `Math.floor(a/b)` to a bitwise operation seems simple enough. – Michael Scheper Jun 21 '21 at 13:56
  • "20% gain in efficiency" you posted results that show tenths of milliseconds difference. That's like my boss bragging he just gave me a 0.001% pay increase. If _tenths of milliseconds_ performance increase is useful to you, just upgrade the server, it'll be cheaper than dev time and you will get ten times the improvement. – James Jul 03 '21 at 19:45
264

ES6 introduces the new Math.trunc method. This allows to fix @MarkElliot's answer to make it work for negative numbers too:

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

Note that Math methods have the advantage over bitwise operators that they work with numbers over 231.

Community
  • 1
  • 1
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • var y =18014398509481984; var x= 5; div = ? - bug ? – 4esn0k Feb 03 '15 at 05:51
  • 6
    @4esn0k It's not a bug. Your number has too many digits, you can't have that much precision in a 64-bit binary format IEEE 754 number. For example, `18014398509481984 == 18014398509481985`. – Oriol Feb 03 '15 at 16:21
  • 18014398509481984 == 2**54, and i specially used this number, because it is represented exactly in binary64 format. and the answer is represented exactly too – 4esn0k Feb 03 '15 at 18:28
  • @4esn0k I didn't explain very well. I meant `18014398509481984 / 5` is `3602879701896396.8`. However, that can't be stored, so it is converted to `3602879701896397`. And then `Math.trunc(3602879701896397)` is `3602879701896397`. – Oriol Feb 03 '15 at 18:40
  • OK, I spent full day thinking how to workaround this rounding too. Seems, it is possible to determine, that there was rounding and correct "truncated quotinent": if (y / x === div && rem > x - rem) { div -= 1; }", but I am not sure in correctness, anyway never mind, your solution is good enough for most of the cases. – 4esn0k Feb 03 '15 at 18:58
  • 1
    I think the choice is simple: You need support for numbers up to 32 bits signed? Use `~~(x/y)`. Need to support bigger numbers up to 54 bits signed? Use `Math.trunc` if you have it, or `Math.floor` otherwise (correct for negative numbers). Need to support even bigger numbers? Use some big number library. – Stijn de Witt Nov 27 '15 at 20:58
  • 5
    for rubyists here from google in search of `divmod`, you can implement it as such: ```function divmod(x, y) { var div = Math.trunc(x/y); var rem = x % y; return [div, rem]; } ``` – Alex Moore-Niemi Nov 24 '16 at 21:43
  • @AlexMoore-Niemi It requires doing the same operation twice, though. Pretty sure the processor will put the quotient and modulus in different registers for one operation, so JS should really provide a mechanism to get both at once. – Jez Dec 22 '22 at 18:59
55

I normally use:

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

It's probably not the most elegant, but it works.

Dem Pilafian
  • 5,625
  • 6
  • 39
  • 67
Wolf Elkan
  • 749
  • 6
  • 2
  • 3
    Nice solution because it avoids the ugliness of parsing or truncating a float. – Dem Pilafian Mar 20 '19 at 00:11
  • 17
    if you need both quotient and remainder, calculate the remainder first and then reuse that value in the expression for the quotient, i.e. quotient = (a - remainder) / b; – gb96 Apr 04 '19 at 03:33
  • 5
    remainder = a % b; quotient = (a - remainder) / b; – Zv_oDD Oct 30 '19 at 01:21
43
var remainder = x % y;
return (x - remainder) / y;
gammax
  • 447
  • 4
  • 2
  • 2
    This version unfortunately fails the test when x = -100 because it returns -34 instead of -33. – Samuel Dec 07 '13 at 01:45
  • 1
    what about "var x = 0.3; var y = 0.01;" ? (thanks to https://github.com/JuliaLang/julia/issues/4156#issuecomment-23324163) – 4esn0k Feb 03 '15 at 07:44
  • 1
    Actually, @Samuel, with negative values, this method returns correct results, or at least it returns the same values as the method using `Math.trunc` :). I checked with 100,3; -100,3; 100,-3 and -100,-3. Of course, a lot of time has passed since your comment and things change. – Marjan Venema Jul 12 '18 at 14:56
29

You can use the function parseInt to get a truncated result.

parseInt(a/b)

To get a remainder, use mod operator:

a%b

parseInt have some pitfalls with strings, to avoid use radix parameter with base 10

parseInt("09", 10)

In some cases the string representation of the number can be a scientific notation, in this case, parseInt will produce a wrong result.

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

This call will produce 1 as result.

  • 13
    `parseInt` should be avoided when possible. Here is Douglas Crockford's warning: "If the first character of the string is 0, then the string is evaluated in base 8 instead of base 10. In base 8, 8 and 9 are not digits, so parseInt("08") and parseInt("09") produce 0 as their result. This error causes problems in programs that parse dates and times. Fortunately, parseInt can take a radix parameter, so that parseInt("08", 10) produces 8. I recommend that you always provide the radix parameter." http://archive.oreilly.com/pub/a/javascript/excerpts/javascript-good-parts/awful-parts.html – Powers Nov 02 '15 at 04:56
  • 5
    In a division, I expect receive a number, not a string, but this is a good point. – Édipo Costa Rebouças Nov 24 '15 at 22:26
  • 4
    @Powers so add the radix. He doesn't say `parseInt` should be avoided; just that there are some gotchas to be aware of. _You must be aware of these things and be prepared to cope._ – None Dec 22 '15 at 15:03
  • 4
    Never call `parseInt` with a number argument. `parseInt` is supposed to parse partially-numerical strings, not truncate numbers. – Oriol Jun 16 '16 at 16:43
  • 4
    Just because things are not originally meant to be used a certain way, it doesn't mean you shouldn't. This answer works. – fregante Mar 25 '17 at 02:24
9

Math.floor(operation) returns the rounded down value of the operation.

Example of 1st question:

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

console.log(z);

Example of 2nd question:

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

console.log(x);
Teocci
  • 7,189
  • 1
  • 50
  • 48
Aetricity
  • 149
  • 1
  • 4
5

JavaScript calculates right the floor of negative numbers and the remainder of non-integer numbers, following the mathematical definitions for them.

FLOOR is defined as "the largest integer number smaller than the parameter", thus:

  • positive numbers: FLOOR(X)=integer part of X;
  • negative numbers: FLOOR(X)=integer part of X minus 1 (because it must be SMALLER than the parameter, i.e., more negative!)

REMAINDER is defined as the "left over" of a division (Euclidean arithmetic). When the dividend is not an integer, the quotient is usually also not an integer, i.e., there is no remainder, but if the quotient is forced to be an integer (and that's what happens when someone tries to get the remainder or modulus of a floating-point number), there will be a non-integer "left over", obviously.

JavaScript does calculate everything as expected, so the programmer must be careful to ask the proper questions (and people should be careful to answer what is asked!) Yarin's first question was NOT "what is the integer division of X by Y", but, instead, "the WHOLE number of times a given integer GOES INTO another". For positive numbers, the answer is the same for both, but not for negative numbers, because the integer division (dividend by divisor) will be -1 smaller than the times a number (divisor) "goes into" another (dividend). In other words, FLOOR will return the correct answer for an integer division of a negative number, but Yarin didn't ask that!

gammax answered correctly, that code works as asked by Yarin. On the other hand, Samuel is wrong, he didn't do the maths, I guess, or he would have seen that it does work (also, he didn't say what was the divisor of his example, but I hope it was 3):

Remainder = X % Y = -100 % 3 = -1

GoesInto = (X - Remainder) / Y = (-100 - -1) / 3 = -99 / 3 = -33

By the way, I tested the code on Firefox 27.0.1, it worked as expected, with positive and negative numbers and also with non-integer values, both for dividend and divisor. Example:

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

Yes, I noticed, there is a precision problem there, but I didn't had time to check it (I don't know if it's a problem with Firefox, Windows 7 or with my CPU's FPU). For Yarin's question, though, which only involves integers, the gammax's code works perfectly.

László Papp
  • 51,870
  • 39
  • 111
  • 135
Cyberknight
  • 156
  • 2
  • 6
5

Use:

const idivmod = (a, b) => [a/b |0, a%b];

There is also a proposal working on it: Modulus and Additional Integer Math

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
nkitku
  • 4,779
  • 1
  • 31
  • 27
4

Alex Moore-Niemi's comment as an answer:

For Rubyists here from Google in search of divmod, you can implement it as such:

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

Result:

// [2, 33]
Alex
  • 503
  • 4
  • 7
  • 3
    Usually, `divmod` uses floored division (`Math.floor`), which differs from truncated division (`Math.trunc`) when negative numbers are involved. This is the case for [NPM `divmod` package](https://www.npmjs.com/package/divmod), [Ruby `divmod`](https://ruby-doc.org/core-2.3.0/Numeric.html#method-i-divmod), [SWI-Prolog `divmod`](http://www.swi-prolog.org/pldoc/doc_for?object=divmod/4) and probably many other implementations, too. – Palec Jul 07 '17 at 09:17
  • 1
    Truncated division gives more naturally looking results than floored division, but compatibility trumps that, IMO. Maybe, there are mathematical or performance reasons for using floored division, too. Note that usually, `divmod` exists because it is performs twice as fast as computing the two operations separately. Providing such a function without this performance benefit might be confusing. – Palec Jul 07 '17 at 09:28
2

If you need to calculate the remainder for very large integers, which the JS runtime cannot represent as such (any integer greater than 2^32 is represented as a float and so it loses precision), you need to do some trick.

This is especially important for checking many case of check digits which are present in many instances of our daily life (bank account numbers, credit cards, ...)

First of all you need your number as a string (otherwise you have already lost precision and the remainder does not make sense).

str = '123456789123456789123456789'

You now need to split your string in smaller parts, small enough so the concatenation of any remainder and a piece of string can fit in 9 digits.

digits = 9 - String(divisor).length

Prepare a regular expression to split the string

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

For instance, if digits is 7, the regexp is

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

It matches a nonempty substring of maximum length 7, which is followed ((?=...) is a positive lookahead) by a number of characters that is multiple of 7. The 'g' is to make the expression run through all string, not stopping at first match.

Now convert each part to integer, and calculate the remainders by reduce (adding back the previous remainder - or 0 - multiplied by the correct power of 10):

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

This will work because of the "subtraction" remainder algorithm:

n mod d = (n - kd) mod d

which allows to replace any 'initial part' of the decimal representation of a number with its remainder, without affecting the final remainder.

The final code would look like:

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);
}
rewritten
  • 16,280
  • 2
  • 47
  • 50
1

If you are just dividing with powers of two, you can use bitwise operators:

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];
}

(The first is the quotient, the second the remainder)

  • Generally, `function divideByPowerOf2(num, exponent) { return [num >> exponent, num & ((1 << exponent) - 1)]; }`. – Palec Sep 13 '17 at 15:20
1
function integerDivison(dividend, divisor) {

    this.Division = dividend/divisor;
    this.Quotient = Math.floor(dividend/divisor);
    this.Remainder = dividend%divisor;
    this.calculate = () => {
        return {Value:this.Division, Quotient:this.Quotient, Remainder:this.Remainder};
    }
}

var divide = new integerDivison(5, 2);
console.log(divide.Quotient)     // To get the quotient of two values
console.log(divide.division)     // To get the floating division of two values
console.log(divide.Remainder)    // To get the remainder of two values
console.log(divide.calculate())  // To get the object containing all the values
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

If you need the quotient for some stupidly big numbers, you can use:

Math.trunc((x/y) + (Number.EPSILON * (2 ** Math.ceil(Math.log2(Math.abs(x/y))))) * Math.sign(x/y))

NOTE: This only works for cases where the x and y values, i.e. the dividend and divisor, are represented accurately, even after any rounding to make them work as integers when they're larger than Number.MAX_SAFE_INTEGER.

For example, if we have:

x = 45000000000000000000000000000 = 4.5e+28
y =   500000000000000000000000000 =   5e+26

Then the answers given on this page give you:

89.99999999999999: x/y
90: Math.trunc((x/y) + (Number.EPSILON * (2 ** Math.ceil(Math.log2(Math.abs(x/y))))) * Math.sign(x/y))
89: Math.floor(x/y)
89: ~~(x/y)
89: (x/y)>>0
89: x/y|0
89: (x-(x%y))/y

The correct answer is 90, so, as you can see, the equation I gave above is the only one which provides a correct answer.

The equation works for negative results as well. If we make x negative then we get:

-89.99999999999999: x/y
-90: Math.trunc((x/y) + (Number.EPSILON * (2 ** Math.ceil(Math.log2(Math.abs(x/y))))) * Math.sign(x/y))
-90: Math.floor(x/y)
-89: ~~(x/y)
-89: (x/y)>>0
-89: x/y|0
-89: (x-(x%y))/y

Only that equation and Math.floor() give the correct answers.

And, just to confirm with some different values that give a slightly larger value:

x = -45000000000000000000000000 = -4.5e+25
y =    500000000000000000000000 =    5e+23

we get:

-90.00000000000001: x/y
-90: Math.trunc((x/y) + (Number.EPSILON * (2 ** Math.ceil(Math.log2(Math.abs(x/y))))) * Math.sign(x/y))
-91: Math.floor(x/y)
-90: ~~(x/y)
-90: (x/y)>>0
-90: x/y|0
-90.00000000000001: (x-(x%y))/y

In this case, Math.floor() and (x-(x%y))/y fail, meaning that, while it may not be fast or pretty, the code given for this answer is the only method which gives correct results in all cases, provided that the divisor and dividend are able to be represented accurately. (Or, at least, all cases that I'm aware of.)

If you want to know how to get the correct remainder for large numbers, see:

Addendum: If you're only working with positive numbers, then you can shorten it to this:

Math.trunc((x/y) + (Number.EPSILON * (2 ** Math.ceil(Math.log2(x/y)))))
HiEv
  • 88
  • 7
0

You can use the ternary operator to decide how to handle positive and negative integer values as well.

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

If the number is a positive, all is fine. If the number is a negative, it will add 1 because of how Math.floor handles negatives.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Josh Weston
  • 1,632
  • 22
  • 23
0

This will always truncate towards zero.

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
    };
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bzim
  • 1,002
  • 9
  • 17
0

Calculating the number of pages may be done in one step:

Math.ceil(x/y)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user1920925
  • 672
  • 6
  • 5
-6

Here is a way to do this. (Personally I would not do it this way, but I thought it was a fun way to do it for an example.) The ways mentioned in previous answers are definitely better as this calls multiple functions and is therefore slower as well as takes up more room in your bundle.

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);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Daniel
  • 1,392
  • 1
  • 5
  • 16