what is the result of 'x modulo y'? - javascript

Citing the ECMAScript spec Section 5.2:
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 if y is positive, the result k of 'x modulo y' is positive regardless of the sign of x.
and if my understanding is right, ToInt32(-1) equals ToInt32(1)?

The notation x modulo y is used internally within the spec to describe the result of certain operations. So yes, the result k of x modulo y is (by definition) of the same sign as y. It is not claimed that the % operator is equivalent to modulo.
If you're interested, the actual spec for % can be found under section 11.5.3. Interestingly, it makes no use of modulo.

Copy pasting from my previous answer here:
Take a % b
1. When both +ve, Modulo & Remainder are one and the same
2. When a is -ve, they are not the same
For example;
a = -10, b = 3
Remainder of -10 % 3 = -1
for Modulo, add a greater multiple of 3 to your 'a' and calculate the remainder.
-10 + 12 = 2
2 % 3 = 2 is your answer

The modulo operation is defined as the mathematical modulo operation:
Mathematical operations such as addition, subtraction, negation,
multiplication, division, and the mathematical functions defined later
in this clause should always be understood as computing exact
mathematical results on mathematical real numbers, which do not
include infinities and do not include a negative zero that is
distinguished from positive zero.
Your question:
ToInt32(-1) equals ToInt32(1)
Well, no:
Let posInt be sign(number) * floor(abs(number)).
posInt = sign(-1) * floor(abs(-1)) = -1;
Let int32bit be posInt modulo 232; that is, a finite integer value k
of Number type with positive sign and less than 232 in magnitude such
that the mathematical difference of posInt and k is mathematically an
integer multiple of 232.
int32bit = posInt mod 4294967296 = -1 mod 4294967296 = 4294967295
(wolfram alpha link for mathematical result)
If int32bit is greater than or equal to 231, return int32bit − 232,
otherwise return int32bit.
Because 4294967295 >= 2147483648, we return 4294967295 - 4294967296, I.E. -1.
If we run the same steps for ToInt32(1), we get 1. So they don't have the same result.

Related

I want to filter only odd negative numbers from an array. Why does n % 2 === 1 not work, but n % 2 !== 0 does?

Write a function that returns only negative odd numbers from an array.
const arr = [4, -7, -6]
I first tried:
let negativeOdd = arr.filter(n => n % 2 === 1 && n < 0);
return negativeOdd;
result was an empty array. []. The answer should be [-5].
But when I replaced n % 2 === 1 with n % 2 !== 0, it workded. I am new to JS and was hopeing somenone could help me understand why this is happening. Thank you.
The modulo % operator in Javascript divides a number by a divisor (in this case 2), and returns the remainder.
-5 divided by 2 is -2.5, or -2 with a remainder of -1. 2 * -2 + -1 = -5
5 divided by 2 is 2.5, or 2 with a remainder of 1. 2 * 2 + 1 = 5
console.log(-5 % 2);
console.log(5 % 2);
A negative odd number gives
n % 2 === -1.
Just try it out. In the console, type
-5 % 2
There are different possible definitions of the modulus with respect to negative numbers. For some implementations, it's always true that 0 <= |a % b| < |b|; this is tantamount to always using the floor() function to find the integer quotient before computing the remainder. There are many languages with this interpretation, including Common Lisp and Python. You can get a negative value out of the % operator in these languages, but only if the divisor is negative; the sign of the dividend doesn't change the sign of the result.
In other languages, -|b| < |a % b| < |b|, and the sign of the result does depend on the sign of the dividend. This is equivalent to obtaining the integer quotient by rounding toward zero before taking the remainder; C is in this category (since C99; previous editions of the spec left it up to the implementation). So is Javascript, which is why -1 % 2 is not 1, but -1.
The first definition is often more useful, but easy to define in terms of the second:
const mod = (a,b) => (a % b + b) % b // mod(-1,2) is 1

Calculate logarithm by hand

I'd like to calculate the mathematical logarithm "by hand"...
... where stands for the logarithmBase and stands for the value.
Some examples (See Log calculator):
The base 2 logarithm of 10 is 3.3219280949
The base 5 logarithm of 15 is 1.6826061945
...
Hoever - I do not want to use a already implemented function call like Math.ceil, Math.log, Math.abs, ..., because I want a clean native solution that just deals with +-*/ and some loops.
This is the code I got so far:
function myLog(base, x)  {
let result = 0;
do {
x /= base;
result ++;
} while (x >= base)
return result;
}
let x = 10,
base = 2;
let result = myLog(base, x)
console.log(result)
But it doesn't seems like the above method is the right way to calculate the logarithm to base N - so any help how to fix this code would be really appreciated.
Thanks a million in advance jonas.
You could use a recursive approach:
const log = (base, n, depth = 20, curr = 64, precision = curr / 2) =>
depth <= 0 || base ** curr === n
? curr
: log(base, n, depth - 1, base ** curr > n ? curr - precision : curr + precision, precision / 2);
Usable as:
log(2, 4) // 2
log(2, 10) // 3.32196044921875
You can influence the precision by changing depth, and you can change the range of accepted values (currently ~180) with curr
How it works:
If we already reached the wanted depth or if we already found an accurate value:
depth <= 0 || base ** curr === n
Then it just returns curr and is done. Otherwise it checks if the logarithm we want to find is lower or higher than the current one:
base ** curr > n
It will then continue searching for a value recursively by
1) lowering depth by one
2) increasing / decreasing curr by the current precision
3) lower precision
If you hate functional programming, here is an imperative version:
function log(base, n, depth = 20) {
let curr = 64, precision = curr / 2;
while(depth-- > 0 && base ** curr !== n) {
if(base ** curr > n) {
curr -= precision;
} else {
curr += precision;
}
precision /= 2;
}
return curr;
}
By the way, the algorithm i used is called "logarithmic search" commonly known as "binary search".
First method: with a table of constants.
First normalize the argument to a number between 1 and 2 (this is achieved by multiplying or dividing by 2 as many times as necessary - keep a count of these operations). For efficiency, if the values can span many orders of magnitude, instead of equal factors you can use a squared sequence, 2, 4, 16, 256..., followed by a dichotomic search when you have bracketed the value.
F.i. if the exponents 16=2^4 works but not 256=2^8, you try 2^6, then one of 2^5 and 2^7 depending on outcome. If the final exponent is 2^d, the linear search takes O(d) operations and the geometric/dichotomic search only O(log d). To avoid divisions, it is advisable to keep a table of negative powers.
After normalization, you need to refine the mantissa. Compare the value to √2, and if larger multiply by 1/√2. This brings the value between 1 and √2. Then compare to √√2 and so on. As you go, you add the weights 1/2, 1/4, ... to the exponent when a comparison returns greater.
In the end, the exponent is the base 2 logarithm.
Example: lg 27
27 = 2^4 x 1.6875
1.6875 > √2 = 1.4142 ==> 27 = 2^4.5 x 1.1933
1.1933 > √√2 = 1.1892 ==> 27 = 2^4.75 x 1.0034
1.0034 < √√√2 = 1.0905 ==> 27 = 2^4.75 x 1.0034
...
The true value is 4.7549.
Note that you can work with other bases, in particular e. In some contexts, base 2 allows shortcuts, this is why I used it. Of course, the square roots should be tabulated.
Second method: with a Taylor series.
After the normalization step, you can use the standard series
log(1 + x) = x - x²/2 + x³/3 - ...
which converges for |x| < 1. (Caution: we now have natural logarithms.)
As convergence is too slow for values close to 1, it is advisable to use the above method to reduce to the range [1, √2). Then every new term brings a new bit of accuracy.
Alternatively, you can use the series for log((1 + x)/(1 - x)), which gives a good convergence speed even for the argument 2. See https://fr.wikipedia.org/wiki/Logarithme_naturel#D%C3%A9veloppement_en_s%C3%A9rie
Example: with x = 1.6875, y = 0.2558 and
2 x (0.2558 + 0.2558³/3 + 0.2558^5/5) = 0.5232
lg 27 ~ 4 + 0.5232 / ln 2 = 4.7548

>>> (Zero-fill right shift) when second oprand is zero

I understand what is Zero-fill right shift and results it yields make perfect sense when second operand is non-zero:
-7 >>> 1
2147483644
Compare with
-7 >> 1
-4
But when second operand is zero:
-7 >> 0
-7 // Looks right!
-7 >>> 0
4294967289 // What? Why?
If I'm shifting zero bits, doesn't it mean I'm not shifting at all? If that's the case, shouldn't it give me back the original number? I would expect -7 >>> 0 === -7
And also
-7 >>> 32
4294967289
Again, by definition, I would expect -7 >>> n === 0 where n >= 32 because all digits become zeros!
Found the internal workings of it in specs.
x >>> 0 will do ToUint32(x)
And
7.1.6 ToUint32 ( argument )
The abstract operation ToUint32 converts argument to one of 232
integer values in the range 0 through 232−1, inclusive. This abstract
operation functions as follows: Let number be ToNumber(argument).
ReturnIfAbrupt(number). If number is NaN, +0, −0, +∞, or −∞, return
+0. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)). Let int32bit be int modulo
232. Return int32bit.
Note Let int32bit be int modulo, and
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 by above convention, -7 mod 2^32 === 2^32 - 7 === 4294967289

What use-cases exist for using >>>= operator with 0? (Unsigned Right Bit Shift)

I recently came across a strange piece of code that uses the >>>= operator (I'll show it later in the question).
The >>> is the unsigned right bit shift operator, as mentioned in What is the JavaScript >>> operator and how do you use it?
The mozilla documentation describes the operator as...
a >>> b shifts a in binary representation b (< 32) bits to the right, discarding bits shifted off, and shifting in zeroes from the left.
Given this knowledge, I have assumed that >>>= is the in-place unsigned right bit shift operator.
The strange piece of code
Remember that piece of code I mentioned at the start? Here it is...
(number) => {
number >>>= 0;
// Do stuff with number...
}
I'm very curious as to why someone would perform an in-place bit shift with 0.
What are the use-cases?
The attempt to find use-cases
In an attempt to answer my question, I wrote a quick script that would iterate through all unsigned 32-bit integers and compare the integer to its (unsigned right shifted by 0) counterpart.
"use strict";
const assertEqual = (a, b, message) => {
if (a !== b) {
throw message
}
}
const START = 0
const END = Math.pow(2, 32) - 1
for (let n = START; n < END; n++) {
let nShifted = n
nShifted >>>= 0
const message = n + " !== (" + n + " >>>= 0) (which is " + nShifted + ")"
assertEqual(n, nShifted, message)
}
console.log("done.")
As expected, the program finished with no exceptions, since bit-shifting by 0 will have no effect.
This, however, would throw an exception if any of the values were negative.
More experimenting
It appears that performing the shift truncates the result into a 32-bit integer, which isn't surprising.
It also appears that when shifting negative integers, the result is the two's complement, which makes sense because it's making the value unsigned.
For example...
x = -1
console.log(x.toString(2)) // '-1'
x >>>= 0
console.log(x.toString(2)) // '11111111111111111111111111111111'
// (Two's complement of -1)
As mentioned in the comments, using the operator on floating-point numbers will truncate the decimal section and result in an integer.
For example...
x = 2.6
x >>>= 0
console.log(x) // '2'
Summary
In-place right shifting by 0 an integer will truncate it to 32 bits and make it unsigned.
Are there any other use cases for this?

Javascript Whole Numbers

How to disregard remainder or decimal values:
Example: var x = 5/2;
Result: x = 2.5;
What i want is that whatever decimal value will be disregarded so the final output should be x = 2;
You could use Math.floor() (round down), Math.ceil() (round up) or Math.round() (round to nearest integer), dependening on how you wanted to remove the decimal.
Example:
if x = 2.5, Math.floor(x) = 2, Math.ceil(x) = 3, Math.round(x) = 3.
For Reference:
Check the fiddle http://jsfiddle.net/BVYDR/
The | operator forces its argument to an integral value by rounding towards zero.
(3.141592654 | 0) === 3
parseInt(5/2) will give you 2

Categories