How to get big power of 2 in decimal or
how to convert big exponential value into decimal value.
I want 2 to the power of 128 in decimal not exponential
what I did till now
tofixed(+exponent)
which again given me the same value.
var num = Math.pow(2, 128);
Actual result = 3.402823669209385e+38
expected some decimal value not exponential value.
You could use BigInt, if implemented.
var num = BigInt(2) ** BigInt(128);
console.log(num.toString());
console.log(BigInt(2 ** 128).toString());
3.402823669209385e+38 is a decimal number (in string form, because it's been output as a string). It's in scientific notation, specifically E-notation. It's the number 3.402823669209385 times 100000000000000000000000000000000000000.
If you want a string that isn't in scientific notation, you can use Intl.NumberFormat for that:
console.log(new Intl.NumberFormat().format(Math.pow(2, 128)));
Note: Although that number is well outside the range that JavaScript's number type can represent with precision in general (any integer above Number.MAX_SAFE_INTEGER [9,007,199,254,740,991] may be the result of rounding), it's one of the values that is held precisely, even at that magnitude, because it's a power of 2. But operations on it that would have a true mathematical result that wasn't a power of 2 would almost certainly get rounded.
I think the default power function won't be able to the results you want.
You can refer to the article below to understand how to create an Power function with big number by yourself.
Demo code is not JS but still quite understandable.
↓
Writing power function for large numbers
Related
I want to define a BigInt number in JavaScript. But when I assign it, the wrong number is stored. In fact 1 is added to the number when storing.
let num = BigInt(0b0000111111111111111111111111111111111111111111111111111111111111)
console.log(num) // Output: 1152921504606846976n
console.log(num.toString(2)) // Output: 1000000000000000000000000000000000000000000000000000000000000
So the number stored is 1152921504606846976, but it should be 11529215046068469765. Why is that?
Converting a Number to a BigInt can't create bits that weren't there before.
0b1 (just like 1) is a Number literal, so it creates a Number.
0b1n (just like 1n) is a BigInt literal, so it creates a BigInt.
By writing BigInt(0b1), you're first creating a Number and then converting that to a BigInt. As long as the value is 1, that works just fine; once the value exceeds what you can losslessly store in a Number [1], you'll see that the value of the final BigInt won't match the literal you wrote down. Whether you use binary (0b...), decimal, or hex (0x...) literals doesn't change any of that.
(And just to be extra clear: there's no reason to write BigInt(123n), just like you wouldn't write Number(123). 123n already is a BigInt, so there's nothing to convert.)
A simple non-BigInt way to illustrate what's happening is to enter 12345678901234567890 into your favorite browser's DevTools console: you can specify Number literals of any length you want, but they'll be parsed into an IEEE754 64-bit "double", which has limited precision. Any extra digits in the literal simply can't be stored, though of course each digit's presence affects the magnitude of the number.
[1] Side note: this condition is more subtle than just saying that Number.MAX_SAFE_INTEGER is the threshold, though that constant is related to the situation: any integral number below MAX_SAFE_INTEGER can be stored losslessly, but there are plenty of numbers above MAX_SAFE_INTEGER that can also be represented exactly. Random example: 1e20.
How can i convert a number, a input from my test case which will be of either integer or float, into a float/string number of always with 8 decimal places? say for example, if my input is 3, then i should convert into '3.00000000', if my input is 53.678, then i should convert into '53.67800000'. I have googled and tried with few conversion types like parsing, toPrecision() but could not convert it. Any help is much appreciated.
expect(a).to.equal(b) // a and be should be of same number with types too
expect(a).to.equal(b)
In JavaScript, Number is a double-precision float.
Its precision cannot be expressed in decimal places, it varies depending on how big the number is. Above Number.MAX_SAFE_INTEGER, for example, the precision is "less than 0 decimal places":
const large = 9007199254740992;
const larger = large + 1;
console.log(large === larger);
To convert a Number to a String with a fixed number of decimal places, use .toFixed(), as #epascarello suggested:
const input = 3;
const str = input.toFixed(8);
console.log(str);
As for doing financial calculations, some say you should never use IEEE 754 floats (such as JavaScript's Numbers), although many of the largest companies in finance do just that.
To be on the safe side, use a bignum library such as big.js.
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.
I set up a system that parses a compact data string into JSON. I'm using a 19 digit number to store ids. Unfortunately any number greater than 17 digits, parseFloat() rounds the last few digits.
This breaks the whole data string. Can I fix this?
For example 8246295522085275215 gets turned into 8246295522085276000. Why is this?
http://jsfiddle.net/RobertWHurst/mhZ7Q/
JavaScript has only one numeric type, which is an IEEE 754 double precision floating-point. That means, you have a maximum of 52 bits of precision, which is a bit more than 15 decimal places.
If you need more precision than that, you have to use a bignum library or work with strings.
Numbers in JavaScript lose precision if they are higher than a certain value.
According to http://www.hunlock.com/blogs/The_Complete_Javascript_Number_Reference, integers are only reliable up to 15 digits (9 * 10^15 to be exact).
Try one of these
1. Use a string
2. Split your number in two and save the smaller parts to an array
3. Bignum library
4. Use a smaller number if you can
I'm performing the following operation in Javascript:
0.0030 / 0.031
How can I round the result to an arbitrary number of places? What's the maximum number that a var will hold?
Modern browsers should support a method called toFixed(). Here's an example taken from the web:
// Example: toFixed(2) when the number has no decimal places
// It will add trailing zeros
var num = 10;
var result = num.toFixed(2); // result will equal 10.00
// Example: toFixed(3) when the number has decimal places
// It will round to the thousandths place
num = 930.9805;
result = num.toFixed(3); // result will equal 930.981
toPrecision() might also be useful for you, there is another excellent example on that page.
For older browsers, you can achieve it manually using Math.round. Math.round() will round to the nearest integer. In order to achieve decimal precision, you need to manipulate your numbers a bit:
Multiply the original number by 10^x
(10 to the power of x), where x is
the number of decimal places you
want.
Apply Math.round()
Divide by 10^x
So to round 5.11111111 to three decimal places, you would do this:
var result=Math.round(5.111111*1000)/1000 //returns 5.111
The largest positive finite value of the number type is approximately 1.7976931348623157 * 10308. ECMAScript-262 3rd ed. also defines Number.MAX_VALUE which holds that value.
To answer Jag's questions:
Use the toFixed() method. Beware; it returns a string, not a number.
Fifteen, maybe sixteen. If you try to get more, the extra digits will be either zeros or garbage. Try formatting something like 1/3 to see what I mean.