Division by zero is not an error in JavaScript: it simply returns infinity or negative
infinity. There is one exception, however: zero divided by zero does not have a well-
defined value, and the result of this operation is the special not-a-number value, printed
as NaN . NaN also arises if you attempt to divide infinity by infinity, or take the square in JavaScript root of a negative number or use arithmetic operators with non-numeric operands that
cannot be converted to numbers.
for Example
1. 0===0 returns True & 1==1 returns true
2. 0/0 returns NaN & 1/1 returns 1
Zero is Number and one is also a number?
I want the explanation? Why this Exactly happens in JavaScript only?
Because Javascript follows the IEEE 754 standard, which defines floating-point arithmetic and specifies this behavior.
Why does the standard specify NaN as the result of these operations? Because there is no sensible value to give them, so instead they have a well-defined insensible value.
Dividing anything by 0 is Infinity. That's a correct answer (from a computation point-of-view, not necessarily a mathematics point-of-view). Imagine doing the division on paper. You'll have an infinite number of operations because you always keep subtracting 0.
The reason most things don't allow dividing by 0 is because they have no way to handle an infinite operation - you wouldn't want your machine crashing every time you tried diving by 0 on your calculator.
This is a good video showing the above. An old mechanical calculator that only knows the rules of addition/subtraction (which is all multiplication/division really is). It never stop running because it can always keep subtracting 0.
JavaScript tries to be nice to programmers who aren't mathematics experts.
Read more about the IEEE 754 design rational.
Ironically, the they are also a number:
typeof NaN;//'number'
typeof Infinity;//'number'
To answer your key question, this is how javascript works.
See the specification here
Applying the / Operator
The / operator performs division, producing the quotient of its operands. The left operand is the dividend and the right operand is the divisor. ECMAScript does not perform integer division. The operands and result of all division operations are double-precision floating-point numbers. The result of division is determined by the specification of IEEE 754 arithmetic:
If either operand is NaN, the result is NaN.
The sign of the result is positive if both operands have the same sign, negative if the operands have different signs.
Division of an infinity by an infinity results in NaN.
Division of an infinity by a zero results in an infinity. The sign is determined by the rule already stated above.
Division of an infinity by a nonzero finite value results in a signed infinity. The sign is determined by the rule already stated above.
Division of a finite value by an infinity results in zero. The sign is determined by the rule already stated above.
Division of a zero by a zero results in NaN; division of zero by any other finite value results in zero, with the sign determined by the rule already stated above.
Division of a nonzero finite value by a zero results in a signed infinity. The sign is determined by the rule already stated above.
In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, the quotient is computed and rounded to the nearest representable value using IEEE 754 round-to-nearest mode. If the magnitude is too large to represent, the operation overflows; the result is then an infinity of appropriate sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of the appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754.
In mathematics, zero, symbolized by the numeric character 0, is both:
In a positional number system, a place indicator meaning "no units of this multiple." For example, in the decimal number 1,041, there is one unit in the thousands position, no units in the hundreds position, four units in the tens position, and one unit in the 1-9 position.
An independent value midway between +1 and -1.
In writing outside of mathematics, depending on the context, various denotative or connotative meanings for zero include "total failure," "absence," "nil," and "absolutely nothing." ("Nothing" is an even more abstract concept than "zero" and their meanings sometimes intersect.)
Brahmagupta developed the concept of the zero as an actual independent number, not just a place-holder, and wrote rules for adding and subtracting zero from other numbers. The Indian writings were passed on to al-Khwarizmi (from whose name we derive the term algorithm ) and thence to Leonardo Fibonacci and others who continued to develop the concept and the number.
Follow the link here
Related
For example:
var a=x.yz;
var b=-x.yz;
after they round to the "error" value, would -a exactly equal to b?
Or would it round to different values like Math.round(2.5) and Math.round(-2.5)?
If the numeral has no more than 20 significant decimal digits, the results of converting a numeral with a - and a numeral without a - are exactly the same except for the sign.
JavaScript is an implementation of ECMAScript, specified in Ecma-262 and ISO/IEC 16262. Ecma-262 specifies that the IEEE-754 64-bit binary floating point format is used, except there is a single NaN value.
Clause 7.1.3.1 specifies how a String (containing a numeral, such as 1.2345) is converted to a Number. Unless the numeral is a decimal numeral with more than 20 significant digits, it is converted as specified in clause 6.1.6, which specifies rounding rules corresponding to IEEE-754’s round-to-nearest-ties-to-even method. That method is symmetric with respect to sign, and therefore the result of converting the negation of a numeral to a JavaScript Number equals the negation of the result of converting the numeral to a Number.
If the numeral has more than 20 significant decimal digits, clause 7.1.3.1 allows an implementation to use either of the two 20-digit numerals nearest the source numeral. The document does not impose further requirements on this choice, so a JavaScript implementation could behave asymmetrically with respect to sign in this case. However, it would be a poor implementation choice to do so.
https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#round-float-
As documentation says Math.random( float ) will round to positive infinity, this will help you to understand why Math.round(2.5) and Math.round(-2.5) returns a different value. So in your case -(-a) will be rounded in fact as +a.
Right shifting a number in javascript sometimes results in a negative number. What is the reason behind that? Can that be mitigated?
const now = 1562143596806 // UNIX timestamp in milliseconds
console.log(now >> 8) // -4783199
Use the zero-fill right shift operator (>>>) to always get a positive result:
const now = 1562143596806 // UNIX timestamp in milliseconds
console.log(now >>> 8)
The reason for the >> operator returning the number is caused by the fact that, originally, the number is internally represented as a 64-bit floating point number:
10110101110110111000000111010000100000110
The bit shift operation will first convert the operand to a 32-bit integer. It does this by keeping only the 32 least significant bits, and discarding the rest:
10110111000000111010000100000110
Then it will shift it by the specified number of bits while maintaining the sign, i.e. shifting in 8 1 bits from the left:
11111111101101110000001110100001
Converting back to decimal, this yields:
-4783199
The basic issue is that 1562143596806 is too large to fit in 32 bits. It can be represented as a Number, but when performing bitwise operations, the value is first converted to a 32bit integer and that means the "top bits" are already dropped before shifting - the upper bits of the result are therefore not filled from the original value, they are copies of the sign of that temporary 32bit value (or with >>>, they would be zero, which is not really an improvement). That the result happens to come out negative is just an accident depending on the exact bit pattern of the input, if it had been positive it would still have been the wrong positive value.
Such large values could be safely manipulated as BigInt, but support for that is lacking. Using floating point arithmetic can work, but requires extra care. For example you can divide by 256 and floor the result, but you cannot use the usual |0 to get rid of the fractional part, because even after dividing by 256 the value is too big to fit in 32 bits. Various non-built-in BigInt libraries exist to deal with this sort of thing too.
I am new to JavaScript programming and referring to Eloquent JavaScript, 3rd Edition by Marijn Haverbeke.
There is a statement in this book which reads like,
"JavaScript uses a fixed number of bits, 64 of them, to store a single number value. There are only so many patterns you can make with 64 bits, which means that the number of different numbers that can be represented is limited. With N decimal digits, you can represent 10^N numbers. Similarly, given 64 binary digits, you can represent 2^64 different numbers, which is about 18 Quintilian (an 18 with 18 zeros after it). That’s a lot."
Can someone help me with the actual meaning of this statement. I am confused as to how the values more than 2^64 are stored in the computer memory.
Can someone help me with the actual meaning of this statement. I am
confused as to how the values more than 2^64 are stored in the
computer memory.
Your questions is related with more generic concepts in Computer Science. For this question Javascript stays at higher level.
Please understand basic concepts for memory and storage first;
https://study.com/academy/lesson/how-do-computers-store-data-memory-function.html
https://www.britannica.com/technology/computer-memory
https://www.reddit.com/r/askscience/comments/2kuu9e/how_do_computers_handle_extremely_large_numbers/
How do computers evaluate huge numbers?
Also for Javascript please see this ECMAScript section
Ref: https://www.ecma-international.org/ecma-262/5.1/#sec-8.5
The Number type has exactly 18437736874454810627 (that is, 264−253+3) values, representing the double-precision 64-bit format IEEE 754 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic, except that the 9007199254740990 (that is, 253−2) distinct “Not-a-Number” values of the IEEE Standard are represented in ECMAScript as a single special NaN value. (Note that the NaN value is produced by the program expression NaN.) In some implementations, external code might be able to detect a difference between various Not-a-Number values, but such behaviour is implementation-dependent; to ECMAScript code, all NaN values are indistinguishable from each other.
There are two other special values, called positive Infinity and negative Infinity. For brevity, these values are also referred to for expository purposes by the symbols +∞ and −∞, respectively. (Note that these two infinite Number values are produced by the program expressions +Infinity (or simply Infinity) and -Infinity.)
The other 18437736874454810624 (that is, 264−253) values are called the finite numbers. Half of these are positive numbers and half are negative numbers; for every finite positive Number value there is a corresponding negative value having the same magnitude.
Note that there is both a positive zero and a negative zero. For brevity, these values are also referred to for expository purposes by the symbols +0 and −0, respectively. (Note that these two different zero Number values are produced by the program expressions +0 (or simply 0) and -0.)
The 18437736874454810622 (that is, 264−253−2) finite nonzero values are of two kinds:
18428729675200069632 (that is, 264−254) of them are normalised, having the form
s × m × 2e
where s is +1 or −1, m is a positive integer less than 253 but not less than 252, and e is an integer ranging from −1074 to 971, inclusive.
The remaining 9007199254740990 (that is, 253−2) values are denormalised, having the form
s × m × 2e
where s is +1 or −1, m is a positive integer less than 252, and e is −1074.
Note that all the positive and negative integers whose magnitude is no greater than 253 are representable in the Number type (indeed, the integer 0 has two representations, +0 and -0).
A finite number has an odd significand if it is nonzero and the integer m used to express it (in one of the two forms shown above) is odd. Otherwise, it has an even significand.
In this specification, the phrase “the Number value for x” where x represents an exact nonzero real mathematical quantity (which might even be an irrational number such as π) means a Number value chosen in the following manner. Consider the set of all finite values of the Number type, with −0 removed and with two additional values added to it that are not representable in the Number type, namely 21024 (which is +1 × 253 × 2971) and −21024 (which is −1 × 253 × 2971). Choose the member of this set that is closest in value to x. If two values of the set are equally close, then the one with an even significand is chosen; for this purpose, the two extra values 21024 and −21024 are considered to have even significands. Finally, if 21024 was chosen, replace it with +∞; if −21024 was chosen, replace it with −∞; if +0 was chosen, replace it with −0 if and only if x is less than zero; any other chosen value is used unchanged. The result is the Number value for x. (This procedure corresponds exactly to the behaviour of the IEEE 754 “round to nearest” mode.)
Some ECMAScript operators deal only with integers in the range −231 through 231−1, inclusive, or in the range 0 through 232−1, inclusive. These operators accept any value of the Number type but first convert each such value to one of 232 integer values. See the descriptions of the ToInt32 and ToUint32 operators in 9.5 and 9.6, respectively.
Probably you have learned about big numbers of mathematics.
For example Avogadro constant is 6.022x10**23
Computers can also store numbers in this format.
Except for two things:
They store it as a binary number
They would store Avogadro as 0.6022*10**24, more precisely
the precision: a value that is between 0 and 1 (0.6022); this is usually 2-8 byte
the size/greatness of the number (24); this is usually only 1 byte because of 2**256 is already a very big number.
As you can see this method can be used to store an inexact value of a very big/small number.
An example of inaccuracy: 0.1 + 0.2 == 0.30000000000000004
Due to performance issues, most engines are often using the normal format, if it makes no difference in the results.
Like the asker of this question, I was wondering why Math.ceil(Math.random() * 10) was not preferred over Math.floor(Math.random() * 10) + 1, and found that it was because Math.random has a tiny (but relevant) chance of returning 0 exactly. But how tiny?
Further research told me that this random number is accurate to 16 decimal places... well, sort of. And it's the "sort of" that I'm curious about.
I understand that floating point numbers work differently to decimals. I struggle with the specifics though. If the number were a strict decimal value, I believe the chances would be one in ten billiard (or ten quadrillion, in the American system) - 1:1016.
Is this correct, or have I messed up, or does the floating point thing make a difference?
JavaScript is a dialect of ECMAScript. The ECMAScript-262 standard fails to specify Math.random precisely. The relevant clause says:
Math.random ( )
Returns a Number value with positive sign, greater than or equal to +0𝔽 but strictly less than 1𝔽, chosen randomly or pseudo randomly with approximately uniform distribution over that range, using an implementation-defined algorithm or strategy. This function takes no arguments.
Each Math.random function created for distinct realms must produce a distinct sequence of values from successive calls.
In the absence of a complete specification, no definitive statement can be made about the probability of Math.random returning zero. Each ECMAScript implementation may choose a different algorithm and need not provide a truly uniform distribution.
ECMAScript uses the IEEE-754 basic 64-bit binary floating-point format for its Number type. In this format, the significand (fraction portion) of the number has 53 bits. Every floating-point number has the form s • f • 2e, where s (for sign) is +1 or −1, f (for fraction) is the significand and is an integer in [0, 253), and e (for exponent) is an integer in [−1074, 971]. The number is said to be normalized if the high bit of f is set (so f is in [252, 253)). Since negative numbers are not a concern in this answer, let s be implicitly +1 for the rest of this answer.
One issue with distributing random numbers in [0, 1) is that the representable values are not evenly spaced. There are 252 representable values in [½, 1)—all those with f in [252, 253) and e = −53. And there are the same number of values in [¼, ½)—all those with f in [252, 253) and e = −54. Since there are the same number of numbers in this interval but the interval is half as long, the numbers are more closely spaced. Similarly, in [⅛, ¼), the spacing halves again. This continues until the exponent reaches −1074, at which point the normal numbers end with f = 252. The numbers smaller than that are said to be subnormal (or zero), with f in [0, 252) and e = −1074, and they are evenly spaced.
One choice about how to distribute the numbers for Math.random is to use only the set of evenly spaced numbers f • 2−53 for f in [0, 253). This uses all the representable values in [½, 1), but only half the values in [¼, ½), one-fourth the values in [⅛, ¼), and so on. This is simple and avoids some oddities in the distribution. If implemented correctly, the probability zero is produced is one in 253.
Another choice is to use all the representable values in [0, 1), each with probability proportional to the distance from it to the next higher representable value. Thus, each representable number in [½, 1) would be chosen with probability 1/253, each representable number in [¼, ½) would be chosen with probability 1/254, each representable number in [⅛, ¼) would be chosen with probability 1/255, and so on. This distribution approximates a uniform distribution on the reals and provides finer precision where the floating-point format is finer. If implemented correctly, the probability zero is produced is one in 21074.
Another choice is to use all the representable values in [0, 1), each with probability proportional to the length of the segment in which the representable value is the nearest representable value of all the real numbers in the segment. I will omit discussion of some details of this distribution except to say it mimics the results one would get by choosing a real number with uniform distribution and then rounding it to a representable value using the round-to-nearest-ties-to-even rule. If implemented correctly, the probability zero is produced is one in 21075. (One problem with this distribution is that a uniform distribution over the reals in [0, 1) will sometimes produce a number so close to 1 that rounding produces 1. This then requires either that Math.random be allowed to return 1 or that the distribution be fudged in some way, perhaps by returning the next lower representable value instead of 1.)
I will note that the ECMAScript specification is sufficiently lax that one might assert that Math.random may distribute the numbers with equal probability for each representable value, ignoring the spacing between them. This would not mimic a uniform distribution over the real numbers at all, and I expect very few people would favor it. However, if implemented, the probability zero is returned is one in 1021 • 252, because there are 252 normalized numbers with exponents from −53 to −1074 (1020 values of e), and 252 subnormal or zero numbers.
I have the following function in JavaScript:
//foo is a number literal
function MyFunc(foo) {
if(foo%15 === 0) {
console.log("bar");
}
}
I want to test the behavior at or around the upper size limit of Number in JavaScript.
Now I know that Numbers in JavaScript are IEEE 64-bit floating point numbers. I also know that IEEE floating point numbers have the concept of sub-normals, and that they lose accuracy significantly during mathematical operations at very large (and very small) values, so does it make more sense to aim for testing around the maximum normal number?
How can I go about this?
Proper implementations of JavaScript will not experience any error evaluating foo%15 == 0, regardless of where the value of foo lies in the floating-point domain. This is essentially because the exact mathematical result of a%b is never greater than a and never greater than b, so it is always in a finer region of the floating-point format, so it can always be represented at least as finely as both a and b, and that is fine enough because subtracting any multiple of b from a never creates finer bits than are in a or b.
Subnormals exist only below (less in magnitude than) normal numbers, hence the prefix “sub”. The maximum finite normal number is the maximum finite number.
According to Wikipedia the maximum representable integer by a double-precision floating point number is 2^53 (9,007,199,254,740,992). This might be a useful upper bound for my test.
9,007,199,254,740,992%15 === 2 //obviously