Javascript evaluates the following code snippet to -1.
-5 % 4
I understand that the remainder theorem states a = bq + r such that 0 ≤ r < b.
Given the definition above should the answer not be 3? Why does JavaScript return -1?
Because it's a remainder operator, not a modulo. But there's a proposal for a proper one.
A quote from Ecma 5.1
remainder r from a dividend n and a divisor d is defined by the
mathematical relation r = n − (d × q)
where q is an integer that is negative only if n/d is negative and
positive only if n/d is positive
Most programming languages use a symmetric modulo which is different than the mathematical one for negative values.
The mathematical modulo can be computed using the symmetric modulo like this:
a mod b = ((a % b) + b) % b
mod mathematical modulo
% symmetric modulo
The reason is that % is not a modulus but a remainder operator. See here
If you're using % to do modular arithmetic, it doesn't matter (conceptually, at least) whether -5 % 4 evaluates to –1 or 3, because those two numbers are congruent modulo 4: for the purposes of modular arithmetic, they're the same.
...if the remainder is nonzero, there are two possible choices for the remainder, one negative and the other positive, and there are also two possible choices for the quotient. Usually, in number theory, the positive remainder is always chosen, but programming languages choose depending on the language and the signs of a and n. (http://en.wikipedia.org/wiki/Modulo_operation)
in python, which takes the sign of divisor:
-5 % 4 == 3 # -5 = (-2) * 4 + 3
in javascript, which takes the sign of divident:
-5 % 4 == -1 # -5 = (-1) * 4 - 1
Related
I'm trying to understand how JS engines convert a JS Number (Float64) to a 32-bit signed integer. I read that one can quickly convert a 64 bit float to a 32 bit signed integer with the bitwise OR like:
-8589934590 | 0 // which gives 2
I can't understand where does the 2 come from. According to the spec, the ToInt32 algorithm does this (the bold text is mine, not the spec's):
Let number be ? ToNumber(argument): -8589934590 is already a Number
If number is NaN, +0, -0, +∞, or -∞, return +0.: No
Let int be the Number value that is the same sign as number and whose magnitude is floor(abs(number)): -8589934590 is already an integer
Let int32bit be int modulo 2³² Since 2³² is positive the result should also be positive. In JS the remainder operator uses the sign of the left operand, so to get a modulo in this case (where -8589934590 is negative), we negate it: let int32bit = 8589934590 % 2**32 // 4294967294 which has 32 bit length 0b11111111111111111111111111111110
If int32bit ≥ 2³¹, return int32bit - 2³²; otherwise return int32bit. int32bit is smaller 2³¹ (since it's negative), so I use int32bit which equals -2 (Even if we consider 0b11111111111111111111111111111110 an unsigned integer, then it's greater 2³¹ and int32bit - 2³² still equals -2
Could someone, please, explain, do I correctly understand the ToInt32 algorithm and the bitwise OR operator?
Your step 4 is wrong. Modulo is defined by the spec as:
The notation “x modulo y” (y must be finite and nonzero) computes a value k of the same sign as y (or zero) such that abs(k) < abs(y) and x-k = q × y for some integer q.
So -8589934590 is our x, and 2**32 is our y, from that we also know that k must be positive. If we choose q = -1 we can solve the equation to k = -4294967294. That is however not a valid solution, as k (negative) does not have the same sign as y (positive). If we choose q = -2 instead, we get k = 2.
So for negative numbers x and positive numbers y, q * y will always have to result in a smaller number than x for k to be positive. Thus if we are transforming that to positive numbers (like you did), we are looking for the larger multiple of the number not the smaller one. E.g. if we take 2 % 3, that'll return 2 (2 - 2 = 3 * 0), whereas -2 modulo 3 will return 1 (-2 -1 = 3 * -1).
Consider this code (node v5.0.0)
const a = Math.pow(2, 53)
const b = Math.pow(2, 53) + 1
const c = Math.pow(2, 53) + 2
console.log(a === b) // true
console.log(a === c) // false
Why a === b is true?
What is the maximum integer value javascript can handle?
I'm implementing random integer generator up to 2^64. Is there any pitfall I should be aware of?
How javascript treat large integers?
JS does not have integers. JS numbers are 64 bit floats. They are stored as a mantissa and an exponent.
The precision is given by the mantissa, the magnitude by the exponent.
If your number needs more precision than what can be stored in the mantissa, the least significant bits will be truncated.
9007199254740992; // 9007199254740992
(9007199254740992).toString(2);
// "100000000000000000000000000000000000000000000000000000"
// \ \ ... /\
// 1 10 53 54
// The 54-th is not stored, but is not a problem because it's 0
9007199254740993; // 9007199254740992
(9007199254740993).toString(2);
// "100000000000000000000000000000000000000000000000000000"
// \ \ ... /\
// 1 10 53 54
// The 54-th bit should be 1, but the mantissa only has 53 bits!
9007199254740994; // 9007199254740994
(9007199254740994).toString(2);
// "100000000000000000000000000000000000000000000000000010"
// \ \ ... /\
// 1 10 53 54
// The 54-th is not stored, but is not a problem because it's 0
Then, you can store all these integers:
-9007199254740992, -9007199254740991, ..., 9007199254740991, 9007199254740992
The second one is called the minimum safe integer:
The value of Number.MIN_SAFE_INTEGER is the smallest integer n such
that n and n − 1 are both exactly representable as a Number value.
The value of Number.MIN_SAFE_INTEGER is −9007199254740991
(−(253−1)).
The second last one is called the maximum safe integer:
The value of Number.MAX_SAFE_INTEGER is the largest integer n such
that n and n + 1 are both exactly representable as a Number value.
The value of Number.MAX_SAFE_INTEGER is 9007199254740991
(253−1).
Answering your second question, here is your maximum safe integer in JavaScript:
console.log( Number.MAX_SAFE_INTEGER );
All the rest is written in MDN:
The MAX_SAFE_INTEGER constant has a value of 9007199254740991. The
reasoning behind that number is that JavaScript uses double-precision
floating-point format numbers as specified in IEEE 754 and can only
safely represent numbers between -(2 ** 53 - 1) and 2 ** 53 - 1.
Safe in this context refers to the ability to represent integers
exactly and to correctly compare them. For example,
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 will
evaluate to true, which is mathematically incorrect. See
Number.isSafeInteger() for more information.
.:: JavaScript only supports 53 bit integers ::.
All numbers in JavaScript are floating point which means that integers are always represented as
sign × mantissa × 2exponent
The mantissa has 53 bits. You can use the exponent to get higher integers, but then they won’t be contiguous, any more. For example, you generally need to multiply the mantissa by two (exponent 1) in order to reach the 54th bit.
However, if you multiply by two, you will only be able to represent every second integer:
Math.pow(2, 53) // 54 bits 9007199254740992
Math.pow(2, 53) + 1 // 9007199254740992
Math.pow(2, 53) + 2 //9007199254740994
Math.pow(2, 53) + 3 //9007199254740996
Math.pow(2, 53) + 4 //9007199254740996
Rounding effects during the addition make things unpredictable for odd increments (+1 versus +3). The actual representation is a bit more complicated but this explanation should help you understand the basic problem.
You can safely use strint library to encode large integers in strings and perform arithmetic operations on them too.
Here is the full article.
Number.MAX_VALUE will tell you the largest floating-point value representable in your JS implementation. The answer will likely be: 1.7976931348623157e+308. But that doesn't mean that every integer up to 10^308 can be represented exactly. As your example code shows, beyond 2^53 only even numbers can be represented, and as you go farther out on the number line the gaps get much wider.
If you need exact integers larger than 2^53, you probably want to work with a bignum package, which allows for arbitrarily large integers (within the bounds of available memory). Two packages that I happen to know are:
BigInt by Leemon
and
Crunch
To supplement to other answers here, it's worth mentioning that BigInt exists. This allows JavaScript to handle arbitrarily large integers.
Use the n suffix on your numbers and use regular operators like 2n ** 53n + 2n. Important to point out that a BigInt is not a Number, but you can do range-limited interoperation with Number via explicit conversions.
Some examples at the Node.js REPL:
> 999999999999999999999999999999n + 1n
1000000000000000000000000000000n
> 2n ** 53n
9007199254740992n
> 2n ** 53n + 1n
9007199254740993n
> 2n ** 53n == 2n ** 53n + 1n
false
> typeof 1n
'bigint'
> 3 * 4n
TypeError: Cannot mix BigInt and other types, use explicit conversions
> BigInt(3) * 4n
12n
> 3 * Number(4n)
12
> Number(2n ** 53n) == Number(2n ** 53n + 1n)
true
The pseudocode for incrementing natural numbers using a recursive algorithm is like this (example from the Algorithm Design Manual by Steven S. Skiena):
Increment(y)
if y = 0 then return(1) else
if (y mod 2) = 1 then
return(2 * Increment(y/2))
else return(y + 1)
I implemented it with JavaScript here: https://repl.it/#danielmai/IncrementalNaturalNumbers
function increment(y) {
if(y == 0) return 1
if(y % 2 == 1) {
return 2 * increment(y / 2)
}
else return y + 1
}
It doesn't work for odd numbers. I found out that JavaScript rounds up numbers with 0.5 or higher, so if y is odd, it will increment twice, i.e 5 -> 7.
I can use Math.floor(y/2) to make it round down, but I assume this function should work regardless of rounding up or down. So my question is, is there a way to correct this recursive function in JS without using Math.floor?
This has nothing to do with javascript rounding numbers up with 0.5 or higher.
Your increment function is asuming x / 2 will return an integer, but in javascript this will give a decimal number when odd. So when doing increment(3), you are recursively calling increment(1.5). As 1.5 % 2 = 1.5, its not == 1 so it ends up returning 2.5. So in the end, you end up returning 2.5 * 2 = 5.
This funcion would indeed work on c++ where if you are working with integers, division will trim trailing decimals. However, in javascript addition +, subtraction -, multiplication *, division /, power **, and modulo % all treat numbers in JavaScript as a double. Only binary operators treat numbers in JavaScript as a signed 32 bit integer.
Javascript doesn't have integer division, so you can't just do 5/2 and expect it to give you 2.
If you're looking for an alternative to Math.floor, this website has you covered. It has all of the alternatives you could ever want, and can check which will be the fastest on your browser.
Twenty modulus six is equal to two, which is the remainder but how to know the the modulus is using the 3 to perform the operation?
20 % 6 = 2
You can use
Math.floor(20 / 6);
for this. It rounds down so you have the largest number possible without decimals.
If you want the quotient, you just have to truncate the division
Math.trunc(20/6) //Return 3
Reference
Modulus is not using the 3, it simply knows that:
20 / 6 = 3, with a remainder of 2
=> 20 % 6 = 2
If you want the 3, you just need the expression:
Math.floor(20 / 6)
(or possibly Math.trunc depending on how you want negative numbers handled - floor rounds towards negative infinity, trunc rounds toward zero).
I have the following code to divide a variable by 100 and power it.
var a = 1;
var b = (a / 100) ^ 2;
The value in 'b' becomes 2 when it should be 0.01 ^ 2 = 0.0001.
Why is that?
^ is not the exponent operator. It's the bitwise XOR operator. To apply a power to a number, use Math.pow():
var b = Math.pow(a / 100, 2);
As to why you get 2 as the result when you use ^, bitwise operators compare the individual bits of two numbers to produce a result. This first involves converting both operands to integers by removing the fractional part. Converting 0.01 to an integer produces 0, so you get:
00000000 XOR 00000010 (0 ^ 2)
00000010 (2)
Try this:
2 ^ 10
It gives you 8. This is easily explained: JS does not have a power operator, but a XOR: MDN.
You are looking for Math.pow (MDN)
Power in javasript is made with Math.pow(x, y) function, not typing ˆ in between.
http://www.w3schools.com/jsref/jsref_pow.asp
Update 2021:
Exponentiation operator is available since ECMAScript 2016.
So, you can do something like:
var b = (a / 100) ** 2;