See "About This JavaScript Site" in JavaScript Index and Introduction.
The value of an ECMA-3 JavaScript Number is stored as a floating-point IEEE Double, for which see also in and via my page Pascal / Delphi / + Types.
JavaScript provides no direct access to the full bit pattern of a Number. The bit pattern can be discovered indirectly (except for NaN), and presented as required in a String; and the Number can be constructed from the bit string. It is not necessary to handle every bit individually.
One can also get the exact value of a Number, as a decimal string. For example, 1/3 is stored in a Number as the bit pattern 0x3fd5555555555555 the exact value of which is 0.333333333333333314829616256247390992939472198486328125.
Integers (up to ±253) are held exactly. But logical operations on Numbers (with the bitwise operators << >> >>> ~ & ^ | ) use 32 bit integers.
The input value should be range-checked, if necessary.
The following sets array A to represent the value of X as four byte-sized Number values.
A = [] ; J = 4 while (J--) { A[J] = X & 0xFF ; X = X>>8 } // X/=256
Form Base Converters can also be used for binary to/from hexadecimal conversion.
Type | S | E | F | S: sign; E: biased exponent; F: fractional part of mantissa | ||||
---|---|---|---|---|---|---|---|---|
Bits | NaN | ±Infinity | ±0 | Denorm | Normal | |||
Single | 1 | 8 | 23 | S, 0xff, >0 | S, 0xff, 0 | S, 0, 0 | S, 0, F | S, E, F |
Double | 1 | 11 | 52 | S, 0x7ff, >0 | S, 0x7ff, 0 | |||
A Number is of the first sort that it matches Denorm : F is preceded by '0.' ; Normal : F is preceded by '1.' |
See also IEEE-754 Calculators by Dr Christopher Vickery.
Code here is for conversion to/from IEEE Single/Double. Conversion to match Single necessarily loses accuracy.
The float code is modularised for minimum repetition. For specific work, functions ...Fwd ...Rev could be in-lined, and screen I/O removed.
The binary is separately computed both as four bytes/words and as Sign Exponent Mantissa. Interconversion would be mere string manipulation.
The float LSB might not always be accurate, though it seems good. The code now allows for NaN and ±Infinity and over-range of Single, and for values needing denormals. Zero is now handled as an extreme denormal. An input Number NaN is deemed to have sign=0 and mantissa=1; every NaN looks the same to JavaScript.
TEST THESE CAREFULLY. I have a Pascal/Delphi program, IEEEBITS in programs/ which does the conversion from Number to Single and Double by type-cast, reliably, for comparison.
Enter a String (number or expression) and press Convert. The String is read into Qty as a Number, and the default conversion back to String is shown in Number. SEM and Bits show Qty as independently converted to binary by the code above (there is a cross-check).
The fields of Bits can be edited.
Then press Reverse (Double is a bit slow for extreme exponents). Complete shows (as a String) the result of converting Bits to a Number; the Value string shows the exact decimal value of Bits, calculated in decimal arithmetic. Check is Value converted to Number and then shown by automatic conversion to String.
Because of the inherent reduction in accuracy, Complete will generally differ from Number. Numbers too small for Single Denormal become zero, and Numbers too large become Infinity. In each case, sign is retained.
Complete should agree with Number.
Try 0.01, 0.06, 0.01+0.06 and 0.07.
Function BigCat is efficiently recursive - Wombat is an iterative equivalent. And EjHCat is cunning. Note the differing behaviour of the various routines when the repeat unit is longer than one character.
Beetle totally changed, 2009-12-26.
N.B. The underlying algorithms are, probably, more or less, the simplest; likewise the actual code. But the code is not necessarily optimum, and the structuring of the details could be rather different in other languages.
More complex routines cacheing intermediate results can be substantially faster.
Recursive functions Combs and Perms combine and permute N elements of Src at a time into Got in all ways. Array All collects the results, for which Function Fn is an example.
Two ways of collecting selections in Got are shown. In Perms character elements are concatenated into a String. In Combs elements are treated as full Objects and pushed onto an Array (but converted into a plus-separated string in Fn for display here).
TestCombs() : Combs(0) : Combs(1) : p q r s t Combs(2) : p+q p+r p+s p+t q+r q+s q+t r+s r+t s+t Combs(3) : p+q+r p+q+s p+q+t p+r+s p+r+t p+s+t q+r+s q+r+t q+s+t r+s+t Combs(4) : p+q+r+s p+q+r+t p+q+s+t p+r+s+t q+r+s+t Combs(5) : p+q+r+s+t
TestPerms() : Perms(0) : Perms(1) : p q r s Perms(2) : pq pr ps qp qr qs rp rq rs sp sq sr Perms(3) : pqr pqs prq prs psq psr qpr qps qrp qrs qsp qsr rpq rps rqp rqs rsp rsq spq spr sqp sqr srp srq Perms(4) : pqrs pqsr prqs prsq psqr psrq qprs qpsr qrps qrsp qspr qsrp rpqs rpsq rqps rqsp rspq rsqp spqr sprq sqpr sqrp srpq srqp
In these, array-handling efficiency has not been considered.
The set of permutations of "Mississippi" is the set of permutations of sorted "Mississippi" ("Miiiippssss"), and sorting is fast enough.
So first sort the input, then after for (;;) insert code for but only if this element differs from the previous - in other words, where successive available elements are indistinguishable, only one should be a candidate.
TryPermDups() : PermDups → 60 : Baaann Baanan Baanna Banaan Banana Bannaa Bnaaan Bnaana Bnanaa Bnnaaa aBaann aBanan aBanna aBnaan aBnana aBnnaa aaBann aaBnan aaBnna aaaBnn aaanBn aaannB aanBan aanBna aanaBn aananB aannBa aannaB anBaan anBana anBnaa anaBan anaBna anaaBn anaanB ananBa ananaB annBaa annaBa annaaB nBaaan nBaana nBanaa nBnaaa naBaan naBana naBnaa naaBan naaBna naaaBn naaanB naanBa naanaB nanBaa nanaBa nanaaB nnBaaa nnaBaa nnaaBa nnaaaB
In simple usage, an array Arr can be initialised like Arr = [3,"4",5] to have Arr.length = 3 elements Arr[0] Arr[1] Arr[2]. The elements can be of any type and can differ in type; an "index" does not have to be an integer. Actually, an Array is an Object with extra properties.
The .length property of an array is read/write. It does not represent the number of elements currently defined in the array, but is related to the numbering of the elements with non-negative integer indexes.
The constructor new Array(N) sets the length to N (rounded towards zero, then considered as unsigned 32-bit).
When a value is given to an element with a non-negative integer index, and .length is not already greater than that index, JavaScript makes it one greater than that index.
Writing to the .length property drops any elements with integer indexes of that value or above.
String(A) shows just the integer-indexed elements, comma-separated, from zero to .length-1, with undefined elements showing as empty substrings.
Approximately.
These are substitutes for methods provided in current systems but not in MS IE 4.
Note that a truly general-purpose substitute method must be at least one of two things : fully compliant under all circumstances with the ECMA standard, and/or fully compliant under all circumstances with the behaviour of the majority of common browsers.
However, when a substitute method is used on a particular page or site it is only necessary that it complies with the user's expectations in the circumstances in which it can actually be called. For example, it may be guaranteed that the arguments are in the obvious range, that the array is non-empty, etc.
A substitute method that is known to be different should be given a distinct name.
To be tested more? :-
Start 3,4,5,6,7,8 push 3,4,5,6,7,8,11,22,33 : 9 pop 3,4,5,6,7,8,11,22 : 33 splice 3,4,5,6,M,W,11,22 : 7,8 shift 4,5,6,M,W,11,22 : 3 unshift 1,2,4,5,6,M,W,11,22 : 9
Needs much more testing.
The Sieve of Eratosthenes is a classical, intrinsically fast method for listing prime numbers; see also the Sieve of Atkin; and Prime Numbers.
For the Estimate, see Prime Number Theorem.
Work should be repeated as little as possible. Intermediate results required repeatedly should be determined once and referenced as required.
Poor : document.getElementById("Fred").rows = 3 document.getElementById("Fred").cols = 66 Good : f = document.getElementById("Fred") f.rows = 3 ; f.cols = 66 Good : with (document.getElementById("Fred")) { rows = 3 ; cols = 66 }
Also, code should be repeated as little as possible; so use functions for such code, if as above will not suffice.
I've not speed-tested; but, except for light use, cached should beat iterative and recursive. It's substantially equivalent to using a lookup table, except that the table it generates is just as long as is needed, and no more.
A better example of cacheing follows.
JAD's Quiz 1995, question #14 - to determine the number of ways (49) to give change, in stated coin of the realm (50, 20, 10, 5 pence), for a given "Total" amount (£1.00).
Translated to JavaScript from Pascal program jad_9514.pas :-
The elements of "Coins" ought to be integers in strict descending order. That order was intended at design time; but now it seems to affect mainly speed when cache is used.
For £1.00 = 100p, cacheing intermediate results changed the time taken from intolerable to imperceptible in Borland Pascal on a 486dx/33.
Note the performance gain here with Cache set; allow for the resolution of timing.