The expression -1 % 7 in JavaScript is giving me -1 as the result. Whereas in Python and Haskell, I found the result to be 6.
Can anyone explain why both have different behaviors? Which one is correct?
I'm going to give a slightly different answer. As others have said, functions can do whatever you define them to and m - x = -x mod m. As a prelude, I'll note that Haskell has two "mod" functions, mod and rem which differ in just this aspect. You can make a case that the mod one is preferable mathematically. The rem one corresponds to what you'd get on an x86 processor. There is, in fact, a third one, the Euclidean one, which may be even better as well as described by Raymond Boute in The Euclidean Definitions of the Functions Div and Mod. The third form always returns a positive modulus. (There are, in fact, at least two other choices that can be made.)
So, Javascript's definition is what you get from most machine mod opcodes. In this sense, it might be preferable as this would make it more efficient to implement. Mathematically, Haskell's and Python's definition is better than Javascript's. There's also a third definition which may be slightly better.
One key property that the Euclidean and Haskell/Python definitions both possess is x mod m = y mod m is equivalent to x = y mod m which Javascript's definition lacks. You can verify by calculating 6 % 7 in Javascript.
Both are correct. Some languages return positive modulo numbers, while others retain their sign.
You can simply add the modulus to your variable to get a positive number, or check if the number is positive or negative before performing the modulus operation and correct the result after to switch between the two.
Pseudocode to convert a%b between the two:
In a language where -1%7 == -1, you do this to get a positive number:
((a%b)+b) % b
And in a language where -1%7 == 6 you can do this to get the signed version:
if a < 0:
return (a%b)-b
else:
return a%b
Both are correct, they just use different conventions regarding the handling of negative operands. For positive numbers, the conventions coincide, but for negative numbers they do not. In Python a % b always has the same sign as b.
In what follows, I'll use Python notation, where // is used for integer division.
Let
q, r = a // b, a % b
Then
a == q * b + r
must be true in any language (assuming a and b are integers, with b not equal to zero). So the way the remainder is handled has to be consistent with the convention used for integer division. In Python, integer division is floor division, i.e., the result is rounded towards negative infinity. In some other languages rounding towards zero is used instead. And in some languages, you get whatever convention the CPU manufacturer decided to implement, so the same code run on different hardware can give different results. As you can imagine, that can be somewhat annoying. :)
The % stands for different operators in JavaScript and in Python.
In JavaScript, the % stands for the Remainder operator. The documentation already points out the difference between the remainder and the modulo operation:
The remainder operator returns the remainder left over when one operand is divided by a second operand. It always takes the sign of the dividend, not the divisor. It uses a built-in modulo function to produce the result, which is the integer remainder of dividing var1 by var2 — for example — var1 modulo var2. There is a proposal to get an actual modulo operator in a future version of ECMAScript, the difference being that the modulo operator result would take the sign of the divisor, not the dividend.
(Emphasis by me)
In contrast to that: In Python, the % stands for the modulo operator. The documentation also makes a statement about the sign:
The % (modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first converted to a common type. A zero right argument raises the ZeroDivisionError exception. [...] The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand [2].
(Emphasis by me)
Both are correct.
To complete the other answers, you can also consider the divmod function in Python:
Take two (non complex) numbers as arguments and return a pair of numbers consisting of their quotient and remainder when using integer division. With mixed operand types, the rules for binary arithmetic operators apply. For integers, the result is the same as (a // b, a % b). For floating point numbers the result is (q, a % b), where q is usually math.floor(a / b) but may be 1 less than that. In any case q * b + a % b is very close to a, if a % b is non-zero it has the same sign as b, and 0 <= abs(a % b) < abs(b).
>>> divmod(-1, 7)
(-1, 6)
Related
I am working with software (Oracle Siebel) that only supports JavaScript expressions with operators multiply, divide, subtract, add, and XOR (*, /, -, +, ^). I don't have other operators such as ! or ? : available.
Using the above operators, is it possible to convert a number to 1 if it is non-zero and leave it 0 if it's already zero? The number may be positive, zero, or negative.
Example:
var c = 55;
var d; // d needs to set as 1
I tried c / c , but it evaluates to NaN when c is 0. d needs to be 0 when c is 0.
c is a currency value, and it will have a maximum of two trailing digits and 12 leading digits.
I am trying to emulate an if condition by converting a number to a Boolean 0 or 1, and then multiplying other parts of the expression.
Use the expression n/n^0.
If n is not zero:
Step Explanation
------- -------------------------------------------------------------------------------
n/n^0 Original expression.
1^0 Any number divided by itself equals 1. Therefore n/n becomes 1.
1 1 xor 0 equals 1.
If n is zero:
Step Explanation
------- -------------------------------------------------------------------------------
n/n^0 Original expression.
0/0^0 Since n is 0, n/n is 0/0.
NaN^0 Zero divided by zero is mathematically undefined. Therefore 0/0 becomes NaN.
0^0 In JavaScript, before any bitwise operation occurs, both operands are normalized.
This means NaN becomes 0.
0 0 xor 0 equals 0.
As you can see, all non-zero values get converted to 1, and 0 stays at 0. This leverages the fact that in JavaScript, NaN^0 is 0.
Demo:
[0, 1, 19575, -1].forEach(n => console.log(`${n} becomes ${n/n^0}.`))
c / (c + 5e-324) should work. (The constant 5e-324 is Number.MIN_VALUE, the smallest representable positive number.) If x is 0, that is exactly 0, and if x is nonzero (technically, if x is at least 4.45014771701440252e-308, which the smallest non-zero number allowed in the question, 0.01, is), JavaScript's floating-point math is too imprecise for the answer to be different than 1, so it will come out as exactly 1.
(((c/c)^c) - c) * (((c/c)^c) - c) will always return 1 for negatives and positives and 0 for 0.
It is definitely more confusing than the chosen answer and longer. However, I feel like it is less hacky and not relying on constants.
EDIT: As #JosephSible mentions, a more compact version of mine and #CRice's version which does not use constants is:
c/c^c-c
A very complicated answer, but one that doesn't depend on limited precision: If you take x^(2**n), this will always be equal to x+2**n if x is zero, but it will be equal to x-2**n if x has a one in the nth place. Thus, for x=0, (x^(2**n)-x+2**n)/(2**(n+1) will always be 1, but it will sometimes be zero for x !=0. So if you take the product of (x^(2**n)-x+2**n)/(2**(n+1) over all n, then XOR that with 1, you will get your desired function. You'll have to manually code each factor, though. And you'll have to modify this if you're using floating points.
If you have the == operator, then (x==0)^1 works.
If x is a floating point number, does
y = x & 1
have a purpose other than checking whether x is odd?
I just read Using bitwise OR 0 to floor a number and wonder, are there other interesting bitwise manipulations?
If x is logically floating point (not intended to be an integer value before the test), & 1 has exactly one purpose: To determine if the truncated value of x is odd (it's a combined truncation and bitwise test). It's not saying if x is odd (-2.9 is neither odd nor even, nor is -3.9, and they give opposite results), and it's not just truncating (because it throws away all but one bit of data); the test is intrinsically combining both effects, and as such, is not useful for anything else when x is an arbitrary floating point value.
As other answer(s) mention, bitwise operations have other legitimate uses, e.g. cryptography, or repurposing an integer as a vector of boolean flags, but that's only relevant for logically integer values; performing floating point math and then relying on specific integer values after truncation, without rounding, is a terrible idea, and will bite you when the result ends up being X.9999999999999999999999994 when you expected it to be (and under "grade school" math, it would be) X+1.
You can use bitwise operators to encode options and flags.
ie. Encoding car features
automaticWindows = 0b1; // 1
manualTransmission = 0b10; // 2
hasAC = 0b100; // 4
hasHeater = 0b1000; // 8
If my car has automatic window and AC, but nothing else, then i'd do this:
myCarOptions = automaticWindows | hasAC;
Then to check if some random car has AC I can do:
if (randomCarOption & hasAC) {
// do something... like turn on AC
}
At the end of the day bitwise operators simply allow you to do logic with the various bits which is the core of how computing works.
I've seen some performance critical javascript code, like the one on this project that makes extensive use of bitwise OR operations with 0. Ex:
GameBoyAdvanceCPU.prototype.write8 = function (address, data) {
address = address | 0;
data = data | 0;
this.memory.memoryWrite8(address | 0, data | 0);
I know about the use case of flooring numbers with "|0", but that isn't the case here, as these are always int's. It looks a bit like asm.js, is this to tell the js engine that we are working with integers, allowing some optimizations? If so, which browsers will make those optimizations?
Any pointers to how this works would be appretiated.
According to JavaScript Performance for Madmen
Wrapping integer arithmetic expressions in ( ) | 0 allows the runtime to be sure that you're doing integer arithmetic instead of floating-point arithmetic. This allows it to avoid checking for overflow and produce faster code in many cases.
and according to the page, it's true for "most" Javascript runtimes, but doesn't say which.
As a second source, Writing Fast JavaScript For Games & Interactive Applications states
To tell JavaScript engine we want to store integer values [...] we could use bitwise or operator:
and a third source from Microsoft's Writing efficient JavaScript page:
[...] explicitly tell the JavaScript runtime to use integer arithmetic [...] use the bitwise or operator
Also, apart from in comments, none of the pages above mention asm.js, so I suspect such optimizations apply in code not explicitly marked as asm/in browsers that don't explicitly recognize it.
Referencing the Ecmascript 5 spec: 11.10 Binary Bitwise Operators, namely
The production A : A # B, where # is one of the bitwise operators in
the productions above (&; ^; |), is evaluated as follows:
Let lref be the result of evaluating A.
Let lval be GetValue(lref).
Let rref be the result of evaluating B.
Let rval be GetValue(rref).
Let lnum be ToInt32(lval).
Let rnum be ToInt32(rval).
Return the result of applying the bitwise operator# to lnum and rnum. The result is a signed 32 bit integer.
And noting that ToInt32() is defined as
Let number be the result of calling ToNumber on the input argument.
If number is NaN, +0, −0, +∞, or −∞, return +0.
Let posInt be sign(number) * floor(abs(number)).
Let int32bit be posInt modulo 2^32; that is, a finite integer value k of Number type with positive sign and less than 2^32 in magnitude such that the mathematical difference of posInt and k is mathematically an integer multiple of 2^32.
If int32bit is greater than or equal to 2^31, return int32bit − 2^32, otherwise return int32bit.
It then logically follows (which you can confirm in your own console) that for example
((Math.pow(2, 32)) + 2) | 0 === 2
(Math.pow(2, 31)) | 0 === -2147483648 === -(Math.pow(2, 31))
And so forth.
Shortly put, the operation turns the number to a 32-bit integer (which has its knacks, see the second example above and the ToInt32() definition for an explanation) and then does a logical or with zero which doesn't change the output beyond the first conversion.
Essentially it's a very cost-efficient way to turn a number into a 32-bit integer because 1) it relies on browser's built-in ToInt32(); and 2) ToInt32(0) short-circuits to 0 (see the spec above) and therefore adds practically no additional overhead.
What it actually does can be seen in this fiddle
It's probing the variable against integer type in this case and either "flooring" or set it to 0 if not an integer.
Thus, there's a tremendous differnece to a = a || 0 which would leave a value of 3.2 untouched.
| operator is bitwise OR. It's used to do a bit by bit OR operation on two integers.
The usage here is a shortcut very similar to logical OR || operator to provide default value, with the exception that the result is integer only (as opposed to string...etc)
address = address | 0;
means "if address is a number, let's use it; otherwise, set it to 0".
If I have the following code in JavaScript:
var index1 = (Math.random() * 6) >> 0;
var index2 = Math.floor(Math.random() * 6);
The results for index1 or index2 are anywhere between 0 and 6.
I must be confused with my understanding of the >> operator. I thought that by using arithmetic shift that the results for index1 would be anywhere between 1 and 6.
I am noticing, however that I don't need to use Math.floor() or Math.round() for index1 if I use the >> operator.
I know I can achieve this by adding 1 to both indexes, but I was hoping there was a better way of ensuring results are from 1 to 6 instead of adding 1.
I'm aware that bitwise operators treat their operands as a sequence of 32 bits (zeros and ones), rather than as decimal, hexadecimal, or octal numbers. For example, the decimal number nine has a binary representation of 1001. Bitwise operators perform their operations on such binary representations, but they return standard JavaScript numerical values.
UPDATE:
I saw the original usage in this CAAT tutorial on line 26 and was wondering whether that would actually return a random number between 1 and 6 and it seems it would only ever return a random number between 0 and 6. So you would never actually see the anim1.png fish image!
Thank you in advance for any enlightenment.
Wikipedia says '(Arithmetic right shifts for negative numbers would be equivalent to division using rounding towards 0 in one's complement representation of signed numbers as was used by some historic computers.)'
Not exactly an answer, but the idea is that >> 0 is really specific and shouldn't be used in general for getting a range between 1 and 6.
Most people would tell you to do
Math.floor((Math.random()*10)+1);
I've recently discovered some other ways to remove the fractional part of numeric values in JavaScript other than Math.floor(n), specifically the double bitwise NOT operator ~~n and performing a bitwise or with 0 n|0.
I'd like to know what are the difference between these approaches and what the different scenarios are where one method is recommended over another.
The operands of all bitwise operators are converted to signed 32-bit integers:
Math.floor(2147483648) // 2147483648
2147483648 | 0 // 2147483648
~~2147483648 // 2147483648
Math.floor(2147483649) // 2147483649
2147483649 | 0 // -2147483647
~~2147483649 // -2147483647
So use Math.floor();
Be clear to the next person looking at your code and use Math.floor().
The performance gain of 1%-40% isn't really worth it, so don't make your code confusing and hard to maintain.
(I entirely agree with josh's answer: favor clear maintainable code.)
Here is an explanation on the other bit-wise approaches:
The bit-wise operators work because they only operator on 32-bit (signed) integers but numbers in JavaScript are all IEEE-754 values. Thus, there is an internal conversion (truncation, not floor!) that happens to operands for bit-wise operators.
The applied bit-wise operation (e.g. n<<0, ~~n or n|0) then acts as an identity function which "does nothing" to the converted values: that is, all of these approaches rely on the same conversion applied to bit-wise operands.
Try n as a negative number or a value outside of [-231, 231-1]:
(-1.23|0) // -1
Math.floor(-1.23) // -2
var x = Math.pow(2, 40) + .5
x|0 // 0
Math.floor(x) // 1099511627776
Happy coding.