Why isn't value obtained after Masking accurate in JavaScript? - javascript

I was trying to extract last 32 bits from a Hex number in Javascript.
var hex = 0x6C469F301DBBC30;
var last32bit = (hex & 0xFFFFFFFF).toString(16);
log(last32bit); //gives 1dbbc40
The result is 1DBBC40. Shouldn't this supposed to be 1DBBC30 ?
Also how do I preserve the 0 before 1DBBC40?

The ECMA standard says:
The Number type has exactly 18437736874454810627 (that is, 264−253+3)
values
Your number is too large to be represented exactly by a Number. You should look for a big number library if you wish to accurately represent large numbers. Perhaps one of these libraries would meet your needs.

Related

How to Read 20 bit integer in javascript?

In JavaScript
I am having a variable of 20 bit(16287008619584270370) and I want to convert it into binary of 64 bit but when I used the binary conversion code(Mentioned below) then it doesn't show me real binary of 64 bit.
var tag = 16287008619584270370;
var binary = parseInt(tag, 10).toString(2);
After dec2bin code implementation:
-1110001000000111000101000000110000011000000010111011000000000000
The correct binary should be:
-1110001000000111000101000000110000011000000010111011000011000010
(last 8 binary changed)
When I checked the problem then I get to know that code only reads the variable up to 16 bit after that it assumes 0000 and shows the binary of this (16287008619584270000).
So finally i need a code from anywhere that convert my whole 20 bit number into its actual binary in java Script.
The problem arises because of the limited precision of 64-bit floating point representation. Already when you do:
var tag = 16287008619584270370;
... you have lost precision. If you output that number you'll notice it will be 370 less. JS cannot represent the given number in its number data type.
You can use the BigNumber library (or the many alternatives):
const tag = BigNumber("16287008619584270370");
console.log(tag.toString(2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/bignumber.js/8.0.1/bignumber.min.js"></script>
Make sure to pass large numbers as strings, as otherwise you already lose precision even before you started.
Future
At the time of writing the proposal for a native BigInt is at stage 3, "BigInt has been shipped in Chrome and is underway in Node, Firefox, and Safari."
That change includes a language extension introducing BigInt literals that have an "n" suffix:
var tag = 16287008619584270370n;
To read more than 16 chars we use BigInt instead of int.
var tag = BigInt("16287008619584270370"); // as string
var binary = tag.toString(2);
console.log(binary);

How to convert from Base36 to Base10 in JS

I have a base36 number 00001CGUMZYCB99J
But if I try convert it in JavaScript to base 10 with
parseInt("00001CGUMZYCB99J", 36);
I get wrong results like 177207000002463650 or 177207000002463648. The expected result is 177207000002463655. I found two websites that get the result right anyway: translatorscafe and dcode.
But how can I do this in JS?
The outcome of that conversion exceeds Number.MAX_SAFE_INTEGER (i.e. the base-10 value is too large to fit in a JavaScript integer), which means you need some sort of arbitrary precision library to do the conversion, for instance biginteger:
const BigInteger = require('biginteger').BigInteger;
let value = BigInteger.parse('00001CGUMZYCB99J', 36);
console.log( value.toString() ) // 177207000002463655
JavaScript stores all values in a double. Therefore, large numbers will have some of the less significant digits changed. If you want to deal with large numbers, you have to use a special library like this BigInteger one.
If you use this library, you can convert between bases like this:
BigInteger.parse("00001CGUMZYCB99J", 36);
Keep in mind that you need to keep using the library, you can't convert it back into a normal number, or you will face the same problem.

Converting big number string to number

What way i can convert string with 16 digits and 2 fraction value to number ?
Currently when I try to convert Number('1234567890123456.12') will became to 1234567890123456. fraction values will be gone.
I just want to confirm without using any third party lib can i convert this string to number ?
Unfortunately not. Javascript represents it's numbers using double precision floating point numbers. At 16 digits, it will only be able to store the integer component and not the part after the decimal point. You will need a bignum library to use this value.
EDIT: for reference the biggest integer you can use in JavaScript is 9,007,199,254,740,991
EDIT2: Thanks to Jeremy you can use a library like bignumberJS.
Your number has too many algorisms, I've created an example that simulates in the first position of the array the maximum length possible in javascript.
var nums = [
"12345678910111.12",
"1.5323",
"-42.7789"
];
nums.forEach(function(n) {
console.log(parseFloat(n).toFixed(2));
});
https://jsfiddle.net/7zzz1qzt/
I have faced issue to convert 18 digit string number to number. It is convert all digit to 0 after 16 digit. I have apply below code. it is working fine for me.
[{"id":${id},"name":"${name}"}]

Parse big binary strings to base 10

I'm having some trouble converting big binary strings to base 10. parseInt(string, 2) should return the int, but when using big strings (1800 characters) it maxes out the variable and just returns Infinity. How can get around that?
A 1800 bit binary number would be well over the maximum possible number value in JavaScript. A regular number datatype will not be able to hold that value, and so JavaScript just calls it Infinity. If you need arbitrarily large numbers, you will have to use some bignum library and probably write a custom string to number function.

Math.pow() not giving precise answer

I've used Math.pow() to calculate the exponential value in my project.
Now, For specific values like Math.pow(3,40), it returns 12157665459056929000.
But when i tried the same value using a scientific Calculator, it returns 12157665459056928801.
Then i tried to traverse the loop till the exponential value :
function calculateExpo(base,power){
base = parseInt(base);
power = parseInt(power);
var output = 1;
gameObj.OutPutString = ''; //base + '^' + power + ' = ';
for(var i=0;i<power;i++){
output *= base;
gameObj.OutPutString += base + ' x ';
}
// to remove the last comma
gameObj.OutPutString = gameObj.OutPutString.substring(0,gameObj.OutPutString.lastIndexOf('x'));
gameObj.OutPutString += ' = ' + output;
return output;
}
This also returns 12157665459056929000.
Is there any restriction to Int type in JS ?
This behavior is highly dependent on the platform you are running this code at. Interestingly even the browser matters even on the same very machine.
<script>
document.write(Math.pow(3,40));
</script>
On my 64-bit machine Here are the results:
IE11: 12157665459056928000
FF25: 12157665459056929000
CH31: 12157665459056929000
SAFARI: 12157665459056929000
52 bits of JavaScript's 64-bit double-precision number values are used to store the "fraction" part of a number (the main part of the calculations performed), while 11 bits are used to store the "exponent" (basically, the position of the decimal point), and the 64th bit is used for the sign. (Update: see this illustration: http://en.wikipedia.org/wiki/File:IEEE_754_Double_Floating_Point_Format.svg)
There are slightly more than 63 bits worth of significant figures in the base-two expansion of 3^40 (63.3985... in a continuous sense, and 64 in a discrete sense), so hence it cannot be accurately computed using Math.pow(3, 40) in JavaScript. Only numbers with 52 or fewer significant figures in their base-two expansion (and a similar restriction on their order of magnitude fitting within 11 bits) have a chance to be represented accurately by a double-precision floating point value.
Take note that how large the number is does not matter as much as how many significant figures are used to represent it in base two. There are many numbers as large or larger than 3^40 which can be represented accurately by JavaScript's 64-bit double-precision number values.
Note:
3^40 = 1010100010111000101101000101001000101001000111111110100000100001 (base two)
(The length of the largest substring beginning and ending with a 1 is the number of base-two significant figures, which in this case is the entire string of 64 digits.)
Haskell (ghci) gives
Prelude> 3^40
12157665459056928801
Erlang gives
1> io:format("~f~n", [math:pow(3,40)]).
12157665459056929000.000000
2> io:format("~p~n", [crypto:mod_exp(3,40,trunc(math:pow(10,21)))]).
12157665459056928801
JavaScript
> Math.pow(3,40)
12157665459056929000
You get 12157665459056929000 because it uses IEEE floating point for computation. You get 12157665459056928801 because it uses arbitrary precision (bignum) for computation.
JavaScript can only represent distinct integers to 253 (or ~16 significant digits). This is because all JavaScript numbers have an internal representation of IEEE-754 base-2 doubles.
As a consequence, the result from Math.pow (even if was accurate internally) is brutally "rounded" such that the result is still a JavaScript integer (as it is defined to return an integer per the specification) - and the resulting number is thus not the correct value, but the closest integer approximation of it JavaScript can handle.
I have put underscores above the digits that don't [entirely] make the "significant digit" cutoff so it can be see how this would affect the results.
................____
12157665459056928801 - correct value
12157665459056929000 - closest JavaScript integer
Another way to see this is to run the following (which results in true):
12157665459056928801 == 12157665459056929000
From the The Number Type section in the specification:
Note that all the positive and negative integers whose magnitude is no greater than 253 are representable in the Number type ..
.. but not all integers with large magnitudes are representable.
The only way to handle this situation in JavaScript (such that information is not lost) is to use an external number encoding and pow function. There are a few different options mentioned in https://stackoverflow.com/questions/287744/good-open-source-javascript-math-library-for-floating-point-operations and Is there a decimal math library for JavaScript?
For instance, with big.js, the code might look like this fiddle:
var z = new Big(3)
var r = z.pow(40)
var str = r.toString()
// str === "12157665459056928801"
Can't say I know for sure, but this does look like a range problem.
I believe it is common for mathematics libraries to implement exponentiation using logarithms. This requires that both values are turned into floats and thus the result is also technically a float. This is most telling when I ask MySQL to do the same calculation:
> select pow(3, 40);
+-----------------------+
| pow(3, 40) |
+-----------------------+
| 1.2157665459056929e19 |
+-----------------------+
It might be a courtesy that you are actually getting back a large integer.

Categories