why does javascript bitwise & on binary numbers increases length of binary string - javascript

In the following code it is my understanding that & is supposed to give a resulting binary string with ones where each corresponding digit on each string are both 1's, however the result I got is: "98435", what I expected was: "101011". Where is my misunderstanding? how can I achieve what I am attempting to do?
const bool = "101011";
const bool2 = "111011";
const and = bool & bool2;
console.log("bool: "+bool+", bool2: "+bool2+", &: "+and);

Javascript, like most languages, assumes humans use base 10 in code
Your code uses STRINGS though
When you use any mathematical operator (except +) Javascript tries to be nice, and make a Number out of the string - but, it's a BASE 10 number (unless the first digit in the string is a 0 and the rest of the digits are octal (0 to 7), in that case, the number is considered to be an BASE 8)
So the string 101011 is "coerced" to be the Number 101011 = 11000101010010011 and 111011 becomes 111011 = 11011000110100011
11000101010010011 (binary) &
11011000110100011 (binary)
-----------------
11000000010000011 (binary) = 98435 (decimal)
However, easy to fix:
const bool = "101011";
const bool2 = "111011";
const and = (parseInt(bool,2) & parseInt(bool2,2)).toString(2);
console.log("bool: "+bool+", bool2: "+bool2+", &: "+and);

Related

How can i get the same number value as given in JavaScript?

I got a number 1267508826984464384 from json response. Here i print the number.
<script>
var num = 1267508826984464384;
console.log(num);
var num = "1267508826984464384";
console.log(num);
</script>
output is
In the first print the output is different from the original value. I need the same value as given.
Is it possible?
JavaScript uses floating point under the hood to store numbers. Floating point double precision, which is what JavaScript uses, can only store 64 bits of data. With the way numbers are represented in this manner, this means that there's a limit to how big a Number can normally be (2^53 - 1 for double precision floating point). Your number in the example has gone over this limit (overflow) and hence is being rounded by JavaScript.
You can use BigInt:
var num = BigInt(1267508826984464384);
console.log(num); // logs 1267508826984464384n, with n representing that it's a BigInt type
var num = "1267508826984464384";
console.log(num); // logs 1267508826984464384
May be helpful to read What Every Programmer Should Know About Floating-Point Arithmetic for more information on why this is the case.
They are different types (int and string, respectfully). What you are seeing in the top example is integer overflow (safely abstracted by JS). You can use a big integer to bypass this issue
const hugeString = BigInt("1267508826984464384")
console.log(hugeString + 1n) // 1267508826984464385n
The type of this is BitInt and it will safely allow you to represent your number as a integer. This type must be treated different and the additions must also be BigInt (as shown in the example above).
BigInt is a built-in object that provides a way to represent whole numbers larger than 253 - 1, which is the largest number JavaScript can reliably represent with the Number primitive and represented by the Number.MAX_SAFE_INTEGER constant. BigInt can be used for arbitrarily large integers.
From MDN. You can use it like so:
const theBiggestInt = 9007199254740991n
const alsoHuge = BigInt(9007199254740991)
// ↪ 9007199254740991n
const hugeString = BigInt("9007199254740991")
// ↪ 9007199254740991n
const hugeHex = BigInt("0x1fffffffffffff")
// ↪ 9007199254740991n
const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111")
// ↪ 9007199254740991n
RegEx for finding numbers and quoting them. Looks for prop value boundaries and a sequence of digits and optionally one period, and replaces inserting with quotes around the number value.
RegEx should be adjusted for maximum length or tolerances for numbers to be quoted as strings.
key or value prefix/suffix can be added, so that a JSON.parse reviver function can recognize them and parse to big.js or BigInt.
In most cases, you probably already know if you might receive a large number, and could probably just use a trivial RegEx replace on the specific property you need.
And, you should be coordinating with the server-side to give the data to you in another form that is safe to consume.
Parsing number strings using BigInt and big.js.
str = String.raw `{"j\"son":1234561251261262131231231231231231231231231232123123123,
"array":
[123123123124124214124124124124.111,
124124124124124124124124124,
124124124124124124124124
]}
`
str = str.replace(/((?:{|,|\[)\s*(?:"(?:[^"]|\\")+"\s*:\s*)?)(\d+\.?\d*)(\s*)(?=,|}|\])/g, `$1"$2"$3`)
// note: capture group $3 is just whitespace, which can normally be ignored; included to be "technically accurate"
console.log(
str,
(BigInt(JSON.parse(str)[`j"son`]) + 1n).toString(),
(Big(JSON.parse(str).array[0]).plus(0.0003)).toFixed()
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/big.js/5.2.2/big.min.js" integrity="sha256-gPNmhPlEOUlyAZomtrYRW/HSIjBOOl2LVxft3rsJpxI=" crossorigin="anonymous"></script>

How to convert an integer to short in javascript

I have on my server side (c#) an integer a:
int a = 65512;
and when I can cast it to short : (short)a is equal to -24
I want to move on this conversion to the client side (javascript)
I tried to convert it to first to binary : a.toString(2) and then do an a.toString(2) & 0xFF but in vain
How can I cast a number to a short one on javascript side ?
You can coerce a number in JavaScript to a particular numeric type by making use of TypedArray's, specifically, Int16Array:
function toShort(number) {
const int16 = new Int16Array(1)
int16[0] = number
return int16[0]
}
console.log(toShort(65512))
JavaScript doesn't have int and short and such, it has number, which is an IEEE-754 double-precision binary floating point type (and typed arrays as in Patrick Roberts' answer). However, for certain operations, it acts like it has a 32-bit integer type.
You could take your number and use bit shifting operators to lose half of that 32-bit value, like this:
var a = 65512;
a = (a << 16) >> 16;
console.log(a);
Another option is to understand that C# is overflowing the number so you can just check it's over the max value for a short which is 32767 (07FFF) and subtract the max value of an int+1 which is 65536 (0x10000). For example:
var number = 65512
var shortValue = number > 0x7FFF ? number - 0x10000 : number;
console.log(shortValue);
JavaScript does not support variable types such as short.
You'll have to handle ensuring the number is in short on the server side and keep it as a string in the JavaScript side.

Generate float in range from HEX hash

How to generate (in JavaScript or Node.JS) float in range from 0.00000000 - 100.00000000 from given long HEX hash? For example SHA-256?
I am open to solutions with crypto library because I using it to generate given hash :)
If you're not concerned about precision loss, and your hex strings are of a fixed length (as with SHA-256), you could simply map from one value space to the other:
function hexStrToFraction(hexStr) {
// Expresses a hexadecimal string of N characters as a fraction
// of one above its maximum possible value (16^N).
// Returns a number between 0 and 1.
return parseInt(hexStr, 16) / Math.pow(16, hexStr.length);
}
function sha256ToPercent(sha256) {
return 100 * hexStrToFraction(sha256);
}
Note that the precision loss is high enough to render the majority of a SHA-256 redundant:
var a = 'b2339969703a8c4b49e4a5c99cca6013ed455f52d06f8f03adb927aee7d9c3c0'
var b = 'b2339969703a8c8b8504772b860b9ed2cb6aa0186ff6750981e7ccd5344e4bf1'
// ^ differences start here
hexStrToFraction(a) === hexStrToFraction(b) // evaluates true

Fastest way to create this number?

I'm writing a function to extend a number with sign to a wider bit length. This is a very frequently used action in the PowerPC instruction set. This is what I have so far:
function exts(value, from, to) {
return (value | something_goes_here);
}
value is the integer input, from is the number of bits that the value is using, and to is the target bit length.
What is the most efficient way to create a number that has to - from bits set to 1, followed by from bits set to 0?
Ignoring the fact that JavaScript has no 0b number syntax, for example, if I called
exts(0b1010101010, 10, 14)
I would want the function to OR the value with 0b11110000000000, returning a sign-extended result of 0b11111010101010.
A number containing p one bits followed by q zero bits can be generated via
((1<<p)-1)<<q
thus in your case
((1<<(to-from))-1)<<from
or much shorter
(1<<to)-(1<<from)
if you have the number 2^q (= 1 shifted left by q) represented as an integer of width p + q bits, it has the representation:
0...010...0
p-1 q
then 2^q - 1 has the representation
0...01...1
p q
which is exactly the opposite of you want. So just flip the bits
hence what you want is NOT((1 LEFT SHIFT by q) - 1)
= ~((1 << q) - 1) in c notation
I am not overly familiar with binary mathematics in JavaScript... But if you need to OR a number with 0b11110000000000, then I assume you would just convert that to decimal (which would get you 15360), and do value | 15360.
Relevant info that you may find useful: parseInt("11110000000000", 2) converts a binary number (specified as a string) to a decimal number, and (15360).toString(2) converts a decimal number (15360 in this case) to a binary number (the result is a string).
Revised solution
There's probably a more elegant and mathematical method, but here's a quick-and-dirty solution:
var S = "";
for(var i=0;i<p;i++)
S += "1";
for(i=0;i<q;i++)
S += "0";
S = parseInt(S, 2); // convert to decimal

javascript float from/to bits

I am trying to perform something that is brain-dead simple in any other language but not javascript: get the bits out of float (and the other way around).
In C/C++ it would be something like
float a = 3.1415;
int b = *((int*)&a);
and vise-versa
int a = 1000;
float b = *((float*)&a);
In C# you can use the BitConverter
...floatBits or something alike in Java... Even in VB6 for Christ's sake you can memcpy a float32 into an int32. How on earth can I translate between and int and a float in javascript?
function DoubleToIEEE(f)
{
var buf = new ArrayBuffer(8);
(new Float64Array(buf))[0] = f;
return [ (new Uint32Array(buf))[0] ,(new Uint32Array(buf))[1] ];
}
You certainly don't get anything low-level like that in JavaScript. It would be extremely dangerous to allow recasting and pointer-frobbing in a language that has to be safe for untrusted potential-attacker web sites to use.
If you want to get a 32-bit IEEE754 representation of a single-precision value in a Number (which remember is not an int either; the only number type you get in JavaScript is double), you will have to make it yourself by fiddling the sign, exponent and mantissa bits together. There's example code here.
function FloatToIEEE(f)
{
var buf = new ArrayBuffer(4);
(new Float32Array(buf))[0] = f;
return (new Uint32Array(buf))[0];
}
Unfortunately, this doesn't work with doubles and in old browsers.
JavaScript uses double (IEEE 754) to represent all numbers
double consists of [sign, exponent(11bit), mantissa(52bit)] fields.
Value of number is computed using formula (-1)^sign * (1.mantissa) * 2^(exponent - 1023). (1.mantissa - means that we take bits of mantissa add 1 at the beginning and tread that value as number, e.g. if mantissa = 101 we get number 1.101 (bin) = 1 + 1/2 + 1/8 (dec) = 1.625 (dec).
We can get value of sign bit testing if number is greater than zero. There is a small issue with 0 here because double have +0 and -0 values, but we can distinguish these two by computing 1/value and checking if value is +Inf or -Inf.
Since 1 <= 1.mantissa < 2 we can get value of exponent using Math.log2 e.g. Math.floor(Math.log2(666.0)) = 9 so exponent is exponent - 1023 = 9 and exponent = 1032, which in binary is (1032).toString(2) = "10000001000"
After we get exponent we can scale number to zero exponent without changing mantissa, value = value / Math.pow(2, Math.floor(Math.log2(666.0))), now value represents number (-1)^sign * (1.mantissa). If we ignore sign and multiply that by 2^52 we get integer value that have same bits as 1.mantissa: ((666 / Math.pow(2, Math.floor(Math.log2(666)))) * Math.pow(2, 52)).toString(2) = "10100110100000000000000000000000000000000000000000000" (we must ignore leading 1).
After some string concat's you will get what you want
This is only proof of concept, we didn't discuss denormalized numbers or special values such as NaN - but I think it can be expanded to account for these cases too.
#bensiu answers is fine, but if find yourself using some old JS interpreter you can use this approach.
Like the other posters have said, JavaScript is loose typed, so there is no differentiation in data types from float to int or vice versa.
However, what you're looking for is
float to int:
Math.floor( 3.9 ); // result: 3 (truncate everything past .) or
Math.round( 3.9 ); // result: 4 (round to nearest whole number)
Depending on which you'd like. In C/C++ it would essentially be using Math.floor to convert to integer from float.
int to float:
var a = 10;
a.toFixed( 3 ); // result: 10.000

Categories