-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
modulo function #21
Comments
The following implementation, of the suggested function, appears to satisfy the criteria described above. /**
* A modulo operation that finds the remainder after division of a dividend
* by divisor, using Donald E. Knuth's floored division.
*
* The remainder will have an absolute value less than the absolute
* value of the divisor. Unlike the ECMAScript remainder (%)
* operator, the remainder will have the same sign as the divisor.
*
* @param {number|BigInt} dividend - A finite number.
* @param {number|BigInt} divisor - A non-zero number.
* @return {number|BigInt} The remainder.
* @throws {TypeError} If exactly one of the parameters is a BigInt.
* @throws {RangeError} If the divisor is 0n.
*/
Math.mod = function ( dividend, divisor ) {
/* based on https://github.com/google/closure-library/blob/v20210106/closure/goog/math/math.js#L68 */
var remainder = dividend % divisor;
if ( remainder * divisor < 0 ) {
remainder += divisor;
}
return remainder;
};
/* if either dividend or divisor is not a number, return NaN */
Math.mod( "a", 1 ); // NaN
Math.mod( 1, "a" ); // NaN
Math.mod( NaN, 1 ); // NaN
Math.mod( 1, NaN ); // NaN
/* if divisor is a zero, return NaN or throw RangeError */
Math.mod( 1, 0 ); // NaN
Math.mod( 1, -0 ); // NaN
Math.mod( 1n, 0n ); // RangeError: Division by zero
/* if dividend is a zero, return the dividend */
Math.mod( 0, 1 ); // 0
Math.mod( -0, 1 ); // -0
Math.mod( 0, Infinity ); // 0
Math.mod( 0, -Infinity ); // 0
Math.mod( -0, Infinity ); // -0
Math.mod( -0, -Infinity ); // -0
Math.mod( 0n, 1n ); // 0n
/* if the dividend is an infinity, return NaN */
Math.mod( Infinity, 1 ); // NaN
Math.mod( -Infinity, 1 ); // NaN
/* if the divisor is an infinity with the same sign as the dividend, return the dividend */
Math.mod( 1, Infinity ); // 1
Math.mod( -1, -Infinity ); // -1
/* if the divisor is an infinity with the opposite sign as the dividend, return the divisor */
Math.mod( -1, Infinity ); // Infinity
Math.mod( 1, -Infinity ); // -Infinity
/* integers */
Math.mod( 4, 3 ); // 1
Math.mod( 4n, 3n ); // 1n
Math.mod( 4, -3 ); // -2
Math.mod( 4n, -3n ); // -2n
Math.mod( -4, 3 ); // 2
Math.mod( -4n, 3n ); // 2n
Math.mod( -4, -3 ); // -1
Math.mod( -4n, -3n ); // -1n
/* non-integers */
Math.mod( 5.5, 2 ); // 1.5
Math.mod( 5.5, -2 ); // -0.5
Math.mod( -5.5, 2 ); // 0.5
Math.mod( -5.5, -2 ); // -1.5 Except corner cases, this is the same as |
My concern is that Even if none of those definitions are ever added (specially And we have another problem (only if more than 2 definitions are added): Should all be merged into 1 Yet another problem is |
In my own library, I named it |
I agree, seems reasonable considering the "most" standard |
Note that these functions would just coerce their arguments to numbers instead. |
I’ve frequently had the need for a non-zero modulo function, where PS: Apparently, Mathematica has a generalized modulo function with variable offset d for this: Math.mod = function ( dividend, divisor, offset = 0 ) {
var remainder = (dividend - offset) % divisor + offset;
if ( remainder * divisor < 0 ) {
remainder += divisor;/*?*/
}
return remainder;
}; (Naively adapted from the code @Andrew-Cottrell had posted.) |
can't you |
I'd like to add a modulo function, different from standard %.
Let's call it Math.mod (x, d).
Motivation: operator % produces the remainder of x diveded by Math.abs(d). There is no function that yields the algebraic modulo of x by d, which is of the same sign as d.
Not having this function handy causes frequent bugs in calendrical computations, including ICUs.
The text was updated successfully, but these errors were encountered: