Math.sqrt() returns infinity? - javascript

Math.sqrt(); seems to work fine with any number less than 310 characters long.
However, any number 310 chars or over will return infinity...
If you want to test it out yourself, here it is on jsfiddle http://jsfiddle.net/gqhk9/2
Anyway, I need to get the square root of numbers including some which are 310 chars and longer.
How can I do that in js?

It's not an issue with Math.sqrt - get rid of the Math.sqrt call and you'll still see infinity. Basically, Javascript can't cope with numbers that big - it runs out of the range of 64-bit floating point IEEE 754 values. You'll need to find some sort of library for handling arbitrary-sized integers.
Note that even for numbers smaller than 10309, you're still going to be losing information after the first ~15 digits. If you care about all of those digits, again you should be looking at specialist maths libraries.
A quick look around the web found BigInt.js referenced a few times, but I don't know how good it is.

Look at Number.MAX_VALUE.
The MAX_VALUE property has a value of approximately 1.79E+308.
Values larger than MAX_VALUE are represented as "Infinity".

Javascript numbers cannot be that big.
If you type
javascript:123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
in your address bar, you'll also get Infinity.
You need to use a bignum library.

The number that you are starting with, 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890, is Infinity, and Math.sqrt(Infinity) is Infinity.
What you need is a big integer library to simulate it, for example, http://www.leemon.com/crypto/BigInt.html; then with that you can take your big integer to the power of 0.5 to calculate the square root.

Related

How to implement parseFloat

Wondering how a low-level implementation of parseFloat such as how it works in JavaScript would be implemented.
All the examples I've seen of typecasting resort to using it at some point, such as this, this, or this. On the other hand, there is this file which is quite large (from here).
Wondering if it is just a very complicated function or there is a straightforward implementation. Wondering just generally how it works if it is too complicated.
Perhaps this is closer to it.
The essential mathematics of parseFloat is very simple, requiring no more than elementary-school arithmetic. If we have a decimal numeral, we can easily convert it to binary by:
Divide the integer part by two. The remainder (zero or one) becomes a bit in a binary numeral we are building. The quotient replaces the integer part, and we repeat until the integer part is zero. For example, starting with 13, we divide to get a quotient of 6 and a remainder of 1. Then we divide 6 to get a quotient of 3 and a remainder of 0. Then 1 and 1, then 0 and 1, and we are done. The bits we produced, in reverse order, were 1101, and that is the binary numeral for 13.
Multiply the sub-integer part by two. The integer part becomes another bit in the binary numeral. Repeat with the sub-integer part until it is zero or we have enough bits to determine the result. For example, with .1875, we multiply by two to get .375, which has an integer part of 0. Doubling again produces .75, which again has an integer part of 0. Next we get 1.5, which has an integer part of 1. Now when the sub-integer part, .5, is doubled, we get 1 with a sub-integer part of 0. The new bits are .0011.
To determine a floating-point number, we need as many bits as fit in the significand (starting with the leading 1 bit from the binary numeral), and, for rounding purposes, we need to know the next bit and whether any bits after that are non-zero. (The information about the extra bits tells us whether the difference between the source value and the bits that fit in the significand is zero, not zero but less than 1/2 of the lowest bit that fits, exactly 1/2 of the lowest bit, or more than 1/2 of the lowest bit. This information is enough to decide whether to round up or down in any of the usual rounding modes.)
The information above tells you when to stop multiplying in the second part of the algorithm. As soon as you have all the significand bits, plus one more, plus you have either one non-zero bit or the sub-integer part is zero, you have all the information you need and can stop.
Then you construct a floating-point value by rounding the bits according to whatever rounding rule you are using (often round-to-nearest-ties-to-even), putting the bits into the significand of a floating-point object, and setting the exponent to record the position of the leading bit of the binary numeral.
There are some embellishments for checking for overflow or underflow or handling subnormal values. However, the basic arithmetic is simply elementary-school arithmetic.
Problems arise because the above uses arbitrary-size arrays and because it does not support scientific notation where an “e” is used to introduce a decimal exponent, as in “2.79e34”. The above algorithm requires that we maintain all the space needed to multiply and divide decimal numerals of any length given to us. Usually, we do not want to do that, and we also want faster algorithms. Note that supporting scientific notation with the above algorithm would also require arbitrary-size arrays. To fill out the decimal numeral for “2.79e34”, we have to fill an array with “27900000000000000000000000000000000”.
So algorithms are developed to do the conversion in smarter ways. Instead of doing exact calculations, we may do precise calculations but carefully analyze the errors produced to ensure they are too small to prevent us from getting the right answer. Also, data may be prepared in advance, such as tables with information about powers of ten, so that we have approximate values of powers of ten already in binary without having to compute them each time a conversion is performed.
The complications of converting decimal to binary floating-point arise out of this desire for algorithms that are fast and use limited resources. Allowing some errors causes a need for mathematical proofs to ensure the computations are correct, and trying to make the routines fast and resource-efficient lead people to think of clever techniques to use, which become tricky and require proof.

How can I store an integer number that's greater than 2147483647 in Javascript?

From what I understand integers range from
-2147483648 through 2147483647
I am confused because I noticed some references to big int in javascript. Can someone explain how I can store an integer number larger than 2147483647?
To get past JavaScript's internal numeric limits, use something like a bignum library (Just a random one I found, research for a good library left as an exercise to OP).
BigInteger.js is an arbitrary-length integer library for Javascript, allowing arithmetic operations on integers of unlimited size, notwithstanding memory and time limitations.
Depending on what you are doing the number, you can handle integers up to +/- (2^53)-1 or 9007199254740991.
While not all browsers support Number.MAX_SAFE_INTEGER yet, you can calculate it with:
Math.pow(2, 53) - 1
Note: This works when in pure math functions, but many bitwise operations are limited to 16 bit integers, as well as the index in arrays.
More details can be found here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
two ways we can store big int
const bigIntVal=123243435454656565657575n;
or
const bigIntVal=BigInt("123243435454656565657575");

Make JavaScript Math.sqrt() print more digits

If I write document.write(Math.sqrt(2)) on my HTML page, I get 1.4142135623730951.
Is there any way to make the method output more than 16 decimal places?
No, there is not. Mathematical operations in Javascript are performed using 64-bit floating point values, and 16 digits of precision is right around the limit of what they can represent accurately.
To get more digits of the result, you will need to use an arbitrary-precision math library. I'm not aware offhand of any of these for Javascript that support square roots, though -- the one I was able to find offhand (Big.js) only supports addition, subtraction, and comparisons.
You can use toPrecision. However, ECMA requries only a precision of up to 21 significant digits:
console.log(Math.sqrt(2).toPrecision(21))
But keep in mind that the precision of real values on computer has some limits (see duskwuff's answer).
See also:
toFixed
toExponential

How can I handle numbers bigger than 17-digits in Firefox/IE7?

For a web application I want to be able to handle numbers up to 64 bits in size.
During testing, I found that javascript (or the browser as a whole) seems to handle as much as 17 digits. A 64-bit number has a maximum of 20 digits, but after the javascript has handled the number, the least significant 3 digits are rounded and set to 0....
Any ideas where this comes from?
More importantly, any idea how to work around it?
In Javascript, all numbers are IEEE double precision floating point numbers, which means that you only have about 16 digits of precision; the remainder of the 64 bits are reserved for the exponent. As Fabien notes, you will need to work some tricks to get more precision if you need all 64 bits.
I think you need to treat them as strings if you have reached Javascript limit (see here)
As others note, JS implements doubles, so you'll have to look elsewhere to handle bigger numbers. BigInt is a library for arbitary precision math for integers.
You could try to split them into two or more numbers (in a class maybe), but you'll might need some arithmetic helper functions to work with them.
Cheers

JavaScript 64 bit numeric precision

Is there a way to represent a number with higher than 53-bit precision in JavaScript? In other words, is there a way to represent 64-bit precision number?
I am trying to implement some logic in which each bit of a 64-bit number represents something. I lose the lower significant bits when I try to set bits higher than 2^53.
Math.pow(2,53) + Math.pow(2,0) == Math.pow(2,53)
Is there a way to implement a custom library or something to achieve this?
Google's Closure library has goog.math.Long for this purpose.
The GWT team have added a long emulation support so java longs really hold 64 bits. Do you want 64 bit floats or whole numbers ?
I'd just use either an array of integers or a string.
The numbers in javascript are doubles, I think there is a rounding error involved in your equation.
Perhaps I should have added some technical detail. Basically the GWT long emulation uses a tuple of two numbers, the first holding the high 32 bits and the second the low 32 bits of the 64 bit long.
The library of course contains methods to add stuff like adding two "longs" and getting a "long" result. Within your GWT Java code it just looks like two regular longs - one doesn't need to fiddle or be aware of the tuple. By using this approach GWT avoids the problem you're probably alluding to, namely "longs" dropping the lower bits of precision which isn't acceptable in many cases.
Whilst floats are by definition imprecise / approximations of a value, a whole number like a long isn't. GWT always holds a 64 bit long - maths using such longs never use precision. The exception to this is overflows but that accurately matches what occurs in Java etc when you add two very large long values which require more than 64 bits - eg 2^32-1 + 2^32-1.
To do the same for floating point numbers will require a similar approach. You will need to have a library that uses a tuple.
The following code might work for you; I haven't tested it however yet:
BigDecimal for JavaScript
Yes, 11 bit are reserved for exponent, only 52 bits containt value also called fraction.
Javascript allows bitwise operations on numbers but only first 32 bits are used in those operations according to Javascript standard specification.
I do not understand misleading GWT/Java/long answers in Javascript/double question though? Javascript is not Java.
Why would anyone need 64 bit precision in javascript ?
Longs sometimes hold ID of stuff in a DB so its important not to lose some of the lower bits... but floating point numbers are most of the time used for calculations. To use floats to hold monetary or similar exacting values is plain wrong. If you truely need 64 bit precision do the maths on the server where its faster and so on.

Categories

Resources