How does ~5 return -6? - javascript

I am asking this question as a follow up to my previous question.
The page at W3chools says:
The examples above uses 4 bits unsigned binary numbers. Because of this ~ 5 returns 10.
Since JavaScript uses 32 bits signed integers, it will not return 10.
It will return -6. 00000000000000000000000000000101 (5)
11111111111111111111111111111010 (~5 = -6)
A signed integer uses the leftmost bit as the minus sign.
Inverting the bits and chopping off the sign bit, the number becomes 1111111111111111111111111111010, which evaluates to 2147483642 in decimal form. According to the page, however, it should evaluate to -6.
Where did I go wrong?

The mistake lies in "chopping off the sign bit" of the 32 bit complemented result. This converts -6 (which has lots of leading 1s in it's binary representation) into a 31 bit positive number which still has lots of leading 1s in its binary representation. The 31 bit number obtained by removing the sign bit from -6 is very close to the maximum positive value of a 32 bit signed number.
You can see the results without removing the 32 bit integer sign bit:
function unsignedNibble( i) {
return i & 0x0f;
}
function signedNumberBits( n) {
var bits = "";
for( var i = 32; i--;) {
bits = "" + (n&1) + bits;
n = n >> 1;
}
return bits;
}
console.log("Unsigned 4 bit: ");
var un5 = unsignedNibble( 5); // unsigned 4 bits of 5
console.log( "un5 = %s ( 0b%s)", un5, un5.toString(2));
var notUn5 = unsignedNibble( ~un5);
console.log( "~un5 = %s ( 0b%s)", notUn5, notUn5.toString(2));
console.log("Signed 32 bit: ");
var sn5 = 5; // signed number 5
console.log( "sn5 = %s ( 0b%s)", sn5, sn5.toString(2));
var notSn5 = ~sn5;
console.log( "~sn5 = %s ( 0b%s)", notSn5, signedNumberBits(notSn5));

#wais
6 is represent as 0000 0110 (0 has been padded)
now to get -6 we have to make 2's Complement for that
Step 1 - Reverse all the bits (1st Complement)
1111 1001
Step 2 - Add 1 (0000 0001)
1111 1001 + 0000 0001 = 1111 1010

In 2's compliment, you add 1 at the end after the bits are all complimented to get the negative number's absolute value.
1111111111111111111111111111010 is complimented to get ...0101 (which is 5), but then you add 1 to get 6. Remembering this was a negative number you're determining, you slap the negative sign on to get -6.

JavaScript binary numbers are stored in two's complement format.
This means that a negative number is the bitwise NOT of the number plus 1. For example:
Binary Representation Decimal value
00000000000000000000000000000101 5
11111111111111111111111111111011 -5
00000000000000000000000000000110 6
11111111111111111111111111111010 -6
00000000000000000000000000101000 40
11111111111111111111111111011000 -40
Source: https://www.w3schools.com/js/js_bitwise.asp

~ operator just do bit change.
such as ~5 = ~(00000101) it returns (11111010) = -6
Don't make ~ operator too complicated.

Related

Why is my for loop with (4^i >= x) as condition becoming infinite in JavaScript? [duplicate]

I have some JavaScript code:
<script type="text/javascript">
$(document).ready(function(){
$('#calcular').click(function() {
var altura2 = ((($('#ddl_altura').attr("value"))/100)^2);
var peso = $('#ddl_peso').attr("value");
var resultado = Math.round(parseFloat(peso / altura2)*100)/100;
if (resultado > 0) {
$('#resultado').html(resultado);
$('#imc').show();
};
});
});
</script>
What does the ^ (caret) symbol mean in JavaScript?
The ^ operator is the bitwise XOR operator. To square a value, use Math.pow:
var altura2 = Math.pow($('#ddl_altura').attr("value")/100, 2);
^ is performing exclusive OR (XOR), for instance
6 is 110 in binary, 3 is 011 in binary, and
6 ^ 3, meaning 110 XOR 011 gives 101 (5).
110 since 0 ^ 0 => 0
011 0 ^ 1 => 1
--- 1 ^ 0 => 1
101 1 ^ 1 => 0
Math.pow(x,2) calculates x² but for square you better use x*x as Math.pow uses logarithms and you get more approximations errors. ( x² ~ exp(2.log(x)) )
Its called bitwise XOR. Let me explain it:
You have :
Decimal Binary
0 0
1 01
2 10
3 11
Now we want 3^2= ?
then we have 11^10=?
11
10
---
01
---
so 11^10=01
01 in Decimal is 1.
So we can say that 3^2=1;
This is the bitwise XOR operator.
The bitwise XOR operator is indicated
by a caret ( ^ ) and, of course, works
directly on the binary form of
numbers. Bitwise XOR is different from
bitwise OR in that it returns 1 only
when exactly one bit has a value of 1.
Source: http://www.java-samples.com/showtutorial.php?tutorialid=820

I don't understand what is happening with this XOR

I am working on this problem.
"Given an array, find the int that appears an odd number of times.
There will always be only one integer that appears an odd number of times."
I came up with this solution online:
function findOdd(A) {
var n = 0;
for(var i = 0; i < A.length; i++){
n = n^A[i];
}
return n;
}
This works but I am not sure why and i was hoping someone could explain it to me. I just don't understand the line:
n = n^A[i];
Could you please tell me what it is doing in this instance?
Xoring any number with itself will result in 0. If you know that there's only one number that appears an odd number of times, the others will cancel themselves out by self-xoring, and the answer will be the remaining number that appears an odd number of times.
XOR of two same numbers is always zero. That is,
A^A=0
So, if you XOR a particular number with itself repeatedly for even number of times, the result will be zero.
Here, initially the value of n is zero. The number that will be XOR-ed even number of times, will result zero. And the number that is present odd number of times, say 2m+1number of times, will result in zero for 2m occurrences, and that same number for the final one occurrence.
This is how this solution works.
^ is an exor bit wise operator . so when you do
1 ^ 1 is 0
0 ^ 1 is 1
1 ^ 0 is 1
0 ^ 0 is 0
so to find the odd number of 1's the following code does is
initially result is arr[0] is 1 .
so in the arrary 0^ 0 becomes 0 and 2 ^ 2 becomes 0 and there are 3 1's so 1^1 gets 0 and with 0 ^1 we are leftout with the number which repeats odd nubmer of times
var arr=[1,1,1,0,0,2,2];
var result=arr[0];
for(var i=1;i<arr.length;i++)
result=result ^ arr[i];
console.log(result);
Hope it helps
Bitwise operators work on 32 bits numbers. Any numeric operand in the operation is converted into a 32 bit number. The result is converted back to a JavaScript number. ^ is a bitwise XOR javascript operator.
Bitwise XOR Operator returns a one in each bit position for which the corresponding bits of either but not both operands are ones.
a XOR b yields 1 if a and b are different. The truth table for the XOR operation is:
a b a XOR b
0 0 0
0 1 1
1 0 1
1 1 0
Explanation for expression n = n^A[i];
let A = [1,2,3,4,5]
for n=0, i=0 => 0 ^ A[0] => 0 ^ 1 => converted to binary 0000 ^ 0001 results to 0001 which is equal to 1
for n=1, i=1 => 1 ^ A[1] => 1 ^ 1 => converted to binary 1111 ^ 0010 results to 1101 which is equal to 13
and so on... Hope this solution helps you to understand the above expression and clear your all doubts.

Is it possible to generate an integer by using Math.random()*80 in JavaScript?

I know even if it can, the probability would be really small but is it theoretically possible?
According to the ECMAScript standard, there is only one number type: the double-precision 64-bit binary format IEEE 754 value (number between -(253 -1) and 253 -1). There is no specific type for integers.
So, are there any IEEE 754 numbers that become integer when multiplied by 80?
80 = 2*2*2*2*5. Since the value is stored using binary fractions, the numbers n/16, where n is in the range [1-15] can all be represented exactly. They also become an integer when multiplied by 80.
So there are at least 15 different values that will result in an integer when multiplied by 80.
Can the random number generator actually produce any of these values? I cannot say. That would depend on the javascript implementation.
... ? Yes :
You want an integer between 0 and 80 ?
var my_integer = parseInt (""+ 80 * Math.random());
EDIT You can also round it (floor,ceil) down & up:
Floor does, e.g. : 76,8=>76
var my_integer = Math.floor( parseInt (""+ 80 * Math.floor()));
Ceil does, e.g. : 76,8=>77
var my_integer = Math.ceil(parseInt (""+ 80 * Math.ceil()));
Yes it's possible. From node console:
> for(var i = 0; i < 1000000000; i++) {
... var rn = Math.random() * 80
... if(rn == Math.round(rn)) {
..... console.log('success')
..... break
..... }
... }
success
undefined
>

How can I check that a bit is set (without bitwise operation)?

Looking at the int 44 — I need Math.CEIL (log(2) 44) of binary places to represent 44.
(answer is 6 places)
6 places :
___ ___ ___ ___ ___ ___
32 16 8 4 2 1
But how can I check that (for example) the bit of 8 is checked or not ?
A simple solution will be do to :
((1<<3) & 44)>0 so this will check if the bit is set.
But please notice that behind the scenes the computer translates 44 to its binary representation and just check if bit is set via bitwise operation.
Another solution is just to build the binary myself via toString(2) or mod%2 in a loop
Question
Mathematically Via which formula, I can test if n'th bit is set ?
(I would prefer a non loop operation but pure single math phrase)
Divide by the value of the bit that you want to check
and test if the first bit is set (this can be tested with x mod 2 == 1)
Math expression:
floor(value/(2^bitPos)) mod 2 = 1
As JS function:
function isSet(value, bitPos) {
var result = Math.floor(value / Math.pow(2, bitPos)) % 2;
return result == 1;
}
Note: bitPos starts with 0 (bit representing the nr 1)
The 'bit' (actually any base) value of an indexed number index in a value val in base base can in general be calculated as
val = 1966;
index = 2;
base = 10;
alert (Math.floor(val/Math.pow(base,index)) % base);
result: 9
val = 44;
index = 3;
base = 2;
alert (Math.floor(val/Math.pow(base,index)) % base);
result: 1 (only 0 and 1 are possible here – the range will always be 0..base-1).
The combination of Math.floor (to coerce to an integer in Javascript) and Math.pow is kind of iffy here. Even in integer range, Math.pow may generate a floating point number slightly below the expected 'whole' number. Perhaps it is safer to always add a small constant:
alert (Math.floor(0.1+val/Math.pow(base,index)) % base);
You can simply check if the bit at the position is set to 1.
function isBitSet(no, index) {
var bin = no.toString(2);
// Convert to Binary
index = bin.length - index;
// Reverse the index, start from right to left
return bin[index] == 1;
}
isBitSet(44, 2); // Check if second bit is set from left
DEMO

Strange javascript operator: expr >>> 0 [duplicate]

This question already has answers here:
What is the JavaScript >>> operator and how do you use it?
(7 answers)
Closed 7 years ago.
the following function is designed to implement the indexOf property in IE. If you've ever had to do this, I'm sure you've seen it before.
if (!Array.prototype.indexOf){
Array.prototype.indexOf = function(elt, from){
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++){
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
I'm wondering if it's common to use three greater than signs as the author has done in the initial length check?
var len = this.length >>> 0
Doing this in a console simply returns the length of the object I pass to it, not true or false, which left me pondering the purpose of the syntax. Is this some high-level JavaScript Ninja technique that I don't know about? If so, please enlighten me!
>>> is the Zero-fill right shift operator. The >>> 0 is an abuse of the operator to convert any numeric expression to an "integer" or non-numeric expression to zero. Here is what it does:
This operator shifts the first operand the specified number of bits to
the right. Excess bits shifted off to the right are discarded. Zero
bits are shifted in from the left. The sign bit becomes 0, so the
result is always positive.
Here is an explanation of the convert-to-integer behavior which applies to all bitwise operations:
Bitwise operators treat their operands as a sequence of 32 bits (zeros
and ones), rather than as decimal, hexadecimal, or octal numbers.
[...] Bitwise operators perform their operations on such binary
representations, but they return standard JavaScript numerical values.
Together, these statements assert that expr >>> 0 will always return a positive number as follows:
expr is cast to a 32-bit integer for bitwise operation
>>> 0 has no effect (no bits are shifted)
The result is converted to a Number
Here are a few expressions and their outcome:
1 >>> 0 // 1 -- Number cast to 32-bit integer then back to Number
"1" >>> 0 // 1 -- String cast to 32-bit integer then back to Number
undefined >>> 0 // 0 -- failed cast yields zero
Other interesting cases:
1.1 >>> 0 // 1 -- decimal portion gets it
-1 >>> 0 // 4294967295 -- -1 = 0xFFFFFFFF
// Number(0xFFFFFFFF) = 4294967295
"A" >>> 0 // 0 -- cast failed
"1e2" >>> 0 // 100 -- 1x10^2 is 100
"1e10" >>> 0 // 1410065408 -- 1x10^10 is 10000000000
// 10000000000 is 0x00000002540BE400
// 32 bits of that number is 0x540BE400
// Number(0x540BE400) is 1410065408
Note: you will notice that none of them return NaN.
Source: LINK
This is the zero-fill right shift
operator which shifts the binary
representation of the first operand to
the right by the number of places
specified by the second operand. Bits
shifted off to the right are discarded
and zeroes are added on to the left.
With a positive number you would get
the same result as with the
sign-propagating right shift operator,
but negative numbers lose their sign
becoming positive as in the next
example, which (assuming 'a' to be
-13) would return 1073741820:
Code:
result = a >>> b;
The >>> (right-shift) binary operator is simply shifting the right-most bits of a number a specified number of times, and padding with zeroes to the left.
Note: In the following examples, the number in braces after a number signals what base it's in. 2 is for binary, 10 for decimal.
For example, 4 >>> 1 would do:
4(10) = 100(2)
4(10) >>> 1(10) = 010(2) = 2(10)
shift once to the right
Other examples:
4(10) >>> 2(10) = 100(2) >>> 2(10) = 001(2) = 1(10)
10(10) >>> 4(10) = 1010(2) >>> 4(10) = 0000(2) = 0(10)
15(10) >>> 1(10) = 1111(2) >>> 1(10) = 0111(2) = 7
The way I remember it is to move the necessary amount of bits to the right, and then write the number. Like, in the last example, I simply moved everything to the right once, so the result is 0111.
Shifting 0 times does...nothing. No idea why it's there.
Behold the zero-fill right-shift operator.
https://developer.mozilla.org/en/JavaScript/Reference/Operators/Bitwise_Operators

Categories

Resources