© J R Stockton, ≥ 2012-08-19

Links within this site :-

**Merlyn Home Page**- Site Index, E-Mail, Copying**JavaScript**:-- Index and Introduction - with About This Site, Code Re-use, Links
**This Page**: Maths :-- General
- Data Types :-
- Operators :-
- Assignments
- Function Parameters
- Conversion Functions
- Trigonometry
- Some Routines :-
- Decimal and Thousands Separators :-
- Numeric Input :-
- Numeric Output :-
- Simple Leading Zeroes - to 0d, 00d/0dd
- Padding
- MOVED - Testing
`.toString(radix)` - Number to English Words

- Programming for Precision
- MOVED - MS IE : Number From Long String

- Uses of Operators
- RegExps, Validation
- Sorting and Order
- Random :-
- Shuffle, Deal, and Draw :-
- Demonstrations :-
- Exact Arithmetic (NEW PAGE) :-
- Miscellany 1 :-
- Rounding 0 - introducing :-
- Date and Time
- Tests
- General
- Alarm
- Include Files

**Other Pages**:-

**See** "About This JavaScript Site" in
JavaScript Index and Introduction.

Page JavaScript Demos contains a
demonstration of code to evaluate an
expression, to find a zero of an expression, to find a peak of an
expression, and to approximate by continued and rational fractions
(*cf. π = 355/113*).

The evaluator is not limited in fact to a single expression, and seems rather useful for testing odd bits of JavaScript. A simpler copy is now in JavaScript/HTML/VBS Quick Trials; it can also do HTML and VBS, and pack text, and indent code. Also :

There are three basic data types: "Boolean", "Number", "String".
Values of the corresponding types are returned by `Boolean(x),
Number(x), String(x)` for any `x`.

There are compound data types :- the type "Object" includes "Array" and "RegExp" as subtypes.

An Object contains something like a table of name-value pairs.

There are six permissible String return values of the operator
`typeof` :- "boolean", "function", "number", "object", "string",
"undefined".

**Note** that input controls return only Strings, even if the
input looks like a number; and that the binary operator + is a string
concatenator if at least one of its two operands is a string ...

Strings are made of 16-bit Unicode characters. There is no practical upper limit on their length; empty strings are not special.

Literal strings are bounded by matching `"` or `'`
characters, and so can contain the other character. The escape character
is `\` which accordingly is represented by `\\`; other
particular cases are `\" \' \n \t \x## \u####` for " ' newline,
tab, hexadecimal ##, and Unicode hexadecimal #### -
`\x## = \u00##`.

Within code, Strings should generally not be used to represent
numbers or Booleans. String input can be converted on input with
unary `+` or `!!` operators respectively, as below.

When a variable is used to store one of two states, the Boolean
values `true / false` should generally be used. It is
inefficient to store, for example, Strings `"yes" / "no"` if
those forms are not used as such for I/O.

When a Boolean is required, only the following values are
considered to mean false :-
`0` (numeric zero), `""` (empty string), `false`,
`NaN`, `null`, `undefined`.

The unary NOT operator `!` gives a Boolean result
from an argument of any type.

The following operators all give a Boolean result :-

! < <= > >= == != === !== && ||

`Boolean()` converts its argument to Boolean, as does the
dual-unary operator `!!`. The following should be equivalent
:-

DocProp = (document.Prop?true:false) DocProp = Boolean(document.Prop) DocProp = document.Prop != null DocProp = !!document.Prop

`Number(BoolExp)` and `+BoolExp` return 0 if the
expression is false and 1 if it is true.

The following should not be used :- `X==true X!=false X==false
X!=true` - instead, use respectively :- `X X !X !X`.

JavaScript currently only has one number type, floating-point, which
is encapsulated as the object type "Number". The actual value is held in
binary as an IEEE 754 / IEC 559 Double.
The range therefore slightly exceeds
±1.7×10^{308}.

There are special values :-

- The single value
`NaN`- Not-A-Number - is unequal to everything, including itself; there is a function`isNaN`(IEEE Doubles can hold many different`NaN`values, but JavaScript does not discriminate between them). - There are two non-finite numbers - plus and minus
`Infinity`; there is a function`isFinite`. - Plus and minus zero are representable and equal, but are distinguishable by comparing their reciprocals with zero.
- Denormals, where the exponent is lowest and the mantissa starts
with 0, have lessened proportional resolution; the smallest are about
±4.94×10
^{-324}.

Integers can only be held accurately up to 53 bits plus
sign, and numbers are only, at best, accurate to 15-16 significant
decimal digits. Any integer from 0 up to
2^{53} = 9,007,199,254,740,992 in magnitude is stored
exactly, but relatively few decimal fractions can be.
Only the numbers obtainable from one of those integers by multiplying by
2^{N-53} for any N in -1023 to +1023 can be held exactly.
Check in detail, though.

For conversion of ordinary values of Number to/from bit strings, and the exact value of Numbers, see in Exact Arithmetic.

A general understanding of the properties and use of floating-point numbers is necessary for almost any arithmetic beyond counting; see Pascal Floating-Point for links to general information on floating-point numbers and arithmetic, and Pascal / Delphi / + Types for data on type Double. IEEE Doubles are handled directly by the FPU of a PC; I don't know the situation on other processors.

Seek the
edited reprint (large: 500K + graphics) of a paper *What Every
Computer Scientist Should Know About Floating-Point Arithmetic*, by
David Goldberg, (1991); while parts are esoteric, much is easy to read.
One URL.

Given that Numbers are Doubles, arithmetic is as exact as possible, but no more. Simple binary fractions are exact, provided no more than 53 bits in all are needed. Operations on integers are exact if the true result and all intermediates are integers within that range, except where bitwise operators are used, when the range is 32-bit.

Note that pound-pence arithmetic, using values such as £12.34, may have unexpected small errors; I find that 3355.53 + 660.97 - 660.97 evaluates to 3355.5299999999997. Do the arithmetic in pence - 335553 + 66097 - 66097 gives 335553 - or be sure to round to pence sufficiently often. 1142.33 + 44545.66 gives 45687.990000000005.

And 1.26+11.67+3.45+2.97 evaluates to 19.349999999999998, not 19.35. Indeed, 0.05+0.01 gives 0.060000000000000005 and 0.06+0.01 gives 0.06999999999999999. Also, -0.07+0.05+0.02 gives -3.469446951953614e-18; this illustrates that code to output non-negative numbers as strings may need to accommodate slightly negative ones.

And 3*0.1 gives 0.30000000000000004, and 1.1*1.1 evaluates to 1.2100000000000001.

Note that, while A+B = B+A, it may be that A+B+C != C+B+A, since that is a comparison of (A+B)+C and (C+B)+A which may round differently; for example, X = [0.03+0.03+0.01, 0.01+0.03+0.03] gives me [0.06999999999999999, 0.07].

Where it is known that a calculated number should have an integer
value, one can use `Math.round()` directly to remove its
rounding errors.

In particular, non-integer computed results should not normally be compared for equality; and generally need rounding for display.

For example, `X*0.01` often differs slightly from `X/100`
- the latter is better, since 100 is stored exactly and 0.01 cannot
be. Example : `X = 35`.

There must be a danger with `Math.trunc() / Math.ceil()`, in
cases where the argument should ideally be an exact integer, that
rounding errors may have placed it on the "wrong side" of the exact value,
after which `trunc / ceil` will give a result differing by one
from what it should ideally be.

The unary + - operators.

The following bitwise operators - `~ << >>
>>> & ^ |` - work on 32-bit integers; conversion
to/from Number is automatic. They are, respectively, `complement,
shift left, shift right arithmetic, shift right, and, xor, or`.

They repay consideration; they seem fast. See in Uses of Operators.

In any case where it may matter, it is important to check the behaviour of any "float-to-integer" type of operation for negative arguments; and any rounding for "half-way" arguments.

Mod on negative numbers has the usual difference from what I
generally need; it gives :-

` (-33 % 10) → -3`
rather than `→ +7` .

A workround is to add a sufficient multiple of the second argument
to the first.

However, `Math.floor` is as I would wish :-

` Math.floor(-2.5) → -3`
and not `→ -2`.

Thus the following code gives the `Mod` that I prefer, an
alternative, and a more expressive `Div`. Note : `Mod`
& `mod` give different results for negative `Y` and
can give slightly different results for non-integer `Y`.

For numbers in the signed 32-bit range, `X|0` truncates
`X` towards zero; it seems quicker than `Math.floor(X)`.

For the fractional part of `X`, use `X % 1.0` or
`Mod(X, 1.0)`.

See also Pascal Maths.

Assigning a value which is a simple number, string, or boolean creates a new copy; changing the copy does not change the original. This is "Pass by Value".

Assigning an Object entity creates a new copy of the pointer to that entity; the original Object is not duplicated. Likewise for Arrays, which are in fact Objects themselves; and String Objects. This is "Pass by Reference".

These appear to behave as for Assignments. Parameters are passed by value, and the value of an object for this purpose is effectively a pointer to it.

So the external values of simple parameters cannot be changed; but the properties of objects can be.

*"Objects, including Arrays, are passed by reference.
Simple variables are always passed by value."*

A string of digits starting with a zero is *sometimes*
considered to be in octal - only, I think, for numeric literals, and
when `parseInt()` has no second parameter, in which case octal
seems probable but deprecated. So `parseInt("09")` cannot be
trusted. A string starting `0x` is by default taken as
hexadecimal.

Results and arguments which represent angles are in radians; one
circle equals 2π radians equals 360 degrees equals 400 grads
equals 6400 mils. Don't enter a numeric value for π, etc.;
use `Math.PI`, etc., assigning its value to a variable if brevity
is needed. Note that `canvas` routines use radians, but SVG
routines use degrees.

The arguments of `Math.atan2()` are, in JavaScript as in other
languages, `(y,x)` *in that order*; some documentation errs
here. Don't try to build `atan2()` from `Math.atan()`;
it's pointless and error-prone. Use `Math.atan2()` in preference
to `Math.atan()` in Cartesian work.

See also Pascal Maths.

Since the JavaScript Number type is an IEEE Double, it can hold factorials only up to 170! (and exactly only up to about 18!). Strings approximating to larger values can be constructed.

Stirling's approximation, to sufficient terms, can also be used to calculate the logarithm of the factorial.

Note that, in some circumstances, a value `2 ^{31} ≤ N
< 2^{32}` may be shown in Hex as a number in

That uses `parsefloat(X, base).toString(radix)`;
the input values are NOT validated.
Even where that approach is unsuitable,
there can be no need to use `Math.pow()`.
Try it with the output base not 10 and the output value large!

Currently (June 2010). `.toString(radix)` is not cross-browser
reliable with non-integer Numbers; the final character can for
example be the radix, or zero.

The operation `N = N & N-1` decrements the number of bits
set in N; somewhere, there is a Web page listing many such operations.

The Decimal Separator (decimal point), where needed, is vital; but thousands separators are mere decoration.

Consider multi-national number formats.

The only decimal separator known to JavaScript (future versions
possibly excepted) is the decimal point, "`.`"; and the language
knows no thousands separator. If the Continental virgule (a comma) is
needed in input or output, it seems to me best to deal with it by using
a RegExp substitution as a pre- or post- processor. Input thousands
separators can be removed with a RegExp; I have code below and elsewhere
to add them in output.

Data which is stored or transmitted should not use a localised format; the format should be fixed and where possible compliant with standards of ISO and similar bodies.

If you see a comma (',') reported as the decimal separator, please tell me : I do not expect it to occur.

JavaScript expects, and gives, a dot as the decimal separator, but Continental usage calls for a comma :-

S = S.replace(/,/, '.') // for input S = S.replace(/\./, ',') // for output

For integers with thousands separators, use the above in the opposite
order and with a RegExp `g` modifier.

For strings with both separators possible, to exchange dot and comma throughout,

S = S.replace(/,/g, '#').replace(/\./g, ',').replace(/#/g, '.')

It may be required that a Number is converted to String, with
integers having trailing "**.**0". Function `TRZ` converts
integers, without harming or rounding other Numbers.

Consider multi-national number formats. Before a thousands separator, India prefers separators two digits apart, to show lakhs, crores, etc. The following can be changed to insert dot rather than comma.

Note that `ThouS` is for non-negative integers,
and `Comma` is for integers.

To insert commas as thousands separators :-

Unicode "`\u20AC`" is the Euro
sign, "€" or "€"; "`\u00A3`" is the Pound sign,
"£". Function `RComma()` can process more than one number in
a string. A "g" does not affect the result; and, in MSIE 4, it did not
significantly affect the speed.
See Regular Expressions.

Commas can be removed from a string for input :-

S = S.replace(/,/g, '') S = S.split(',').join()

The `.value` properties of JavaScript text-input controls are
of type String.

After possible pre-processing, the quantity represented by an input string may need to be used as a Number. If so, usually it should immediately (but after any pattern validation; see RegExps & Validation) be converted to Number type.

One can use, to convert String `S` to Number, any of : `+S
-S Number(S) parseInt(S) parseInt(S,B) parseFloat(S)`, or any other
operator requiring an arithmetic operand. Different converters have
differing properties.

Unlike the unary operators, `parseFloat/parseInt` disregard
trailing non-numerics. All of those conversions disregard whitespace;
all disregard leading zeroes, except sometimes for
`parseInt(S)`.

The unary `+` operator converts its argument to type "number".
For converting String to Number, it seems preferable to `parseInt /
parseFloat` except when their special properties are required.
It is shorter and faster.

Unary `+` is a good way to fix the `'1' + '1' = '11'`
problem (FAQ, 6.4). In
reading a control,
`V1 = + document.forms['AForm'].Min1.value` makes
`V1` a number; without the `+` it still would be a
string.

While `typeof(0+'')` gives `'string'`,
`typeof(+'')` gives `'number'`.

The unary `-` operator is similar;
so `- -` (not `--`) is in effect
a numeric `+` operator.

They take numbers as decimal unless starting with `0x` (or
`0X`), meaning hexadecimal; a leading zero does not mean octal. Leading whitespace is ignored; leading
or trailing non-numerics give `NaN`.
An empty string gives zero.

See also The unary + operator by Brad Fults.

`Number()` can be expected to behave as unary `+`.

`S+0 S-0 S*1 S/1` are deprecated, as calling for an
unnecessary operation; use `+S`.

Remember that if `parseInt` is given only one argument, and
that starts with zero, then the argument is generally taken as octal
(unless starting with `0x`, when as hexadecimal); giving two
arguments is safer. Except for leading whitespace and sign, the first
non-numeric character terminates the number.

Remember that a literal integer is interpreted as
hexadecimal if the numeric part starts with `0x`.

Function `parseInt(S, 10)` can be used to read the integer
part of a decimal fixed-point number, independently of which decimal
separator is used, if any.

When a zero is returned by `parseInt / parseFloat`, it is
correctly signed.

For converting a possibly signed base-`B` digit string `S`
to a Number, function `parseInt` should be used only when
beneficial, as it is longer and slower than alternatives.

For values of numeric properties, given in decimal without a leading
zero and possibly followed by a unit (such as when getting the value of
a style property, *e.g.* `33px`), `parseInt(S)` is
appropriate.

Bases 2 to 7, 9, 11 to 15, 17 to 36 always require `parseInt(S,
B)`.

In bases 8, 10 and 16, a string `S` of non-negative integer
value with non-numeric parts removed (*e.g.* `09kg` has been
trimmed to `09`), can be of the forms :-

S B Conversion Note 0123 8 use parseInt(S, 8) 1 0123 10 unary + preferred 2 2345 10 unary + preferred 2 0x6b4 16 unary + preferred 6b4 16 use parseInt(S, 16) Notes : 1: B is needed to work with all browsers and with ECMA-262 3rd Edn 2: Commonly use parseInt when converting the value of form controls to Number

Note : `+'0x1'` differs from `parseFloat('0x1')`
and `+''` differs `from parseFloat('')`.

ECMA-262's global function `parseFloat` is decimal-only,
handling such as `3.142 864e5`.

A function such as `parseFloat(S, R)` can be written in
JavaScript, with or without the use of ECMA-262's global functions,
with two different ends in mind :-

- to provide a reasonably fast and accurate function to fill the
gap left by ECMA, in which case its behaviour with malformed inputs
should match that of ECMA
`parseFloat(S)`, - to provide a function of guaranteed accuracy for testing, in which case it need only handle well-formed inputs.

For approximate and exact routines, see in Exact Arithmetic.

For rounding to a given number of decimal places or significant figures, see my Rounding 0.

Only a string can have a leading zero; these functions always return a string. Some of these, and others, are tested and timed at String and Number Formatting.

To bring integers in 0-9 to two digits, or 0-99 to three digits, by adding leading zeroes, without mistreating out-of-range numbers :-

This may sometimes be better; it also accepts Number parameters, and Hex strings (==1 or <2 ?) :-

This prefixes single digits within word boundaries throughout :-

For more, use `SpcsTo() / ZeroTo / ChrsTo`, or build on one
of `PadNumber#()` which assume `Num>=0`.

This has moved into Some Bugs in JavaScript Implementations.

Script version ≥ #1

Use at your own risk; it is not tested enough for use with real currency or on cheques.

Is there interest in the reverse operation?

For a Number `X` which may be negative, use `Math.abs(X)`
after dealing with the sign.

For non-integers, obtain the integer and fractional parts of the
Number `X` with `|0 %0` and treat separately.

Arithmetic on non-integers is usually inexact, but sometimes, with cate and understanding, it can be made strictly exact.

Money calculations using integer-euros-point-cents will be unreliable. It is generally better to work in integer cents; it may be useful to work in submultiples (such as Delphi's "currency", a 64-bit integer "comp" scaled by 10000).

Subtraction of similar non-integers leads to increased relative
errors. For example, the algebraic formula for the roots of a quadratic
includes a `±` sign. Rather than using both directly, it
will be better to obtain the first root by whichever sign gives an
augmentation and the second by then using the formula for the ratio of
the roots.

Where possible, remove factors common to the numerator and
denominator of an overall expression, as in
`B = π * A ; ... ; C = B / π ;`
and similarly with addition and subtraction.

It is better to multiply or divide by an integer than to divide or
multiply by its reciprocal. To see that there can be a difference,
evaluate `35/100 - 35*0.01` for example.

Getting a base-10 lograrithm by dividing a base-*e* logarithm by
a constant is inexact. Try `Math.log(1000)/Math.log(10)` for
example.

Converting from exact algebra to optimum executable code is an art which should be attempted only with care and consideration.

Consolidated into Some Bugs in JavaScript Implementations.