© J R Stockton, ≥ 2012-11-20

Links within this site :-

**Merlyn Home Page**- Site Index, E-Mail, Copying**JavaScript**:-- Index and Introduction - with About This Site, Code Re-use, Links
- Rounding 0
**This Page**:-- Rounding a Number to a Number :-
- Formatting a Number to a Decimal String :-
- The
*Status Quo*:- - Sign Functions
- The Native Methods :-
- Using the Native Converter, Indirectly :-
- Good Conversions to String -
includes
`StrU(), StrT(), StrS(), StrW()` - See also in Rounding 2

- Good Conversions to String -
includes
- Converting
*Ab Initio*to String

- The
- Rounding to N Significant Figures :-
- Extending Right to N Decimals

- Rounding 2
- Rounding 3
- Include Files

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

The standard methods of `Math` are not always adequate.

To integer, towards zero :-

Alternatively, with `((0 < X) - (X < 0))` for the sign.

To integer, towards zero, for |X| < 2^{31} :-

These methods are not substantially dependent on what the rounded number is to be a multiple of.

Signed, to a multiple of Q, for any Q != 0 :-

Signed, to a multiple of 1/R, for any R != 0 :-

The second of the above methods seems less susceptible to internal rounding error, in the common case where R = 1/Q is integer. Try rounding 3.315 to hundredths.

Signed, to 2 decimal places :-

Signed, to N decimal places (N of either sign) :-

Normal convention, outside JavaScript, is to present a string using a fixed number of decimal places, with trailing zeroes shown. For tabulation, a fixed number of characters before the decimal point is usually needed. Thousands separators, for which see in and near JavaScript Maths, may be called for.

Generally, a number held in a string should either have no decimal point or have at least one digit on each side of its decimal point (see, for example, IUPAP SUNAMCO red book (1987).

The simple automatic JavaScript conversion, by using a number in a string context, as here, often does not give the format needed.

Options that may be provided include whether :-

- a "+" is supplied, suppressed, or represented by a space;
- a number less than unity has the zero before the decimal point supplied, suppressed, or represented by a space;
- a number with no decimal places has the decimal point supplied, suppressed, or represented by a space;
- the string should be left-padded, and how, to make the string a specified length,
- the decimal separator is ".", ",", or otherwise;
- values +0 & -0 are discriminated;
- values
`+Infinity -Infinity NaN null undefined`are properly shown.

To return a sign character; alternatives may be preferred :-

function Sign(X) { return (X<0 ? '-' : '') }

A definite indication of positive sign, with a fixed length, may be needed :-

Function `Sygn` always gives a sign, and discriminates between
+0 and -0.

JavaScript ought to provide reliable native Number-to-String routines with the power of those of more mature languages, including fixed-length output.

All browsers have `Number.toString()`. All modern browsers
have `Number.toFixed()`, `Number.toExponential()` and
`Number.toPrecision()`.

On its own, `Number.toString()` is not sufficient in
this context, since the format is variable; it is the same as for the
"automatic" conversions such as in `new String( number)`.

Native `Number.toFixed(N)` is not wholly reliable. It gives
errors in Microsoft JScript and Windows
Script Host. I have seen none in FireFox, Safari, or
Chrome.

As specified, `X.toFixed()` and `X.toFixed(0)` round
half-integers away from zero ; `Math.round(X)` towards `+∞`. IE 8, Firefox 3.0.12, Safari 4.0, Chrome 2.0
comply; Opera 9.64 does Bankers' Rounding for `X.toFixed(0)`, but
Opera 10.0 is correct.

In JScript (at least including IE 8 with JScript 5.8.18702),
`X.toFixed(A)` wrongly rounds towards zero when
`|X|×10 ^{A}` is in the range [0.50, 0.95). For
example,

To determine where the value changes : go to
Find Zero, enter an expression such as
`+X.toFixed(0) ± 0.5` and limits of,
say, -1 and +1, and press Find.

MS IE 8, at least, does Bankers' Rounding.

A method `toFixed` can be added if the system does not already
have it, or can replace the original.

A `toFixed()` *of my own*, based on other general
functions, results possibly differing from those for ECMA-262 and/or in
correct browsers, can be loaded by file inc-cmmn.js. The *currently-loaded* routine
is tested here and below. If the first box contains
a reference to `StrS` then `toFixed` is the substitute; if
it contains `[native]` or similar then it is the browser's.

Note that a leading or trailing decimal point is deprecated in
technical and scientific circles; but `StrS` gives what it
is asked to give.

Another (seemingly OK; much as posted by DA in
news:m.p.s.j 20031106; described as "follows ECMA-262, step-by-step") is
specifically an implementation of `toFixed` without the errors.

There is now
`Number.toExponential()`
and
`Number.toPrecision()`
- the latter uses either the former or `Number.toFixed`,
as necessary. If the browser knows them, tests follow.

Results are compared numerically; a difference of 1 in the last place
may be ignored.

Firefox 3.0.12 allows N=100, contrary to specification.

Firefox 3.0.12 allows N=100, contrary to specification.

Some methods have an upper limit where the native JavaScript number-to-string switches to e-format.

Methods need to be tested to ensure correct rounding into the final place, and to ensure that numbers requiring a first digit of zero are correctly handled.

"Defective Conversions to String", "Satisfactory Conversions to String", "Another Conversion to String", "Other Good? Conversions to String" are in Rounding 2.

For a version to handle the results of approximate calculation of nominally-exact values, such as 1.345 to be rounded to two decimal places, see also Rounding of Approximate Quantities.

The sign function used should be chosen in accord with circumstances.

These seem to be good functions, all returning strings. The input
`X` is expected, but not obliged, to be of type Number.
Providing a function, an object, or an array of length not 1 is
not recommended.

`Sign(X)` : return "+" or " " or "-" ;
constant width 1 character
`PrfxTo(S, L, C)`
: prefix copies of `C`
to a copy of `S` while it is shorter than `L`
`SpcsTo(S, L)` :
prefix spaces to a copy
of `S` while it is shorter than `L`
`ChrsTo(S, L, C)` : prefix copies of character `C`
to a copy of `S` while it is shorter than `L`
`StrU(X, M, N)` : convert non-negative number `X` to
a string of `M` digits Point `N` digits
`StrS(X, M, N)` :
prefix `Sign(X)` to `StrU(Abs(X), M, N)`
`StrS(X, M, N)` : as `StrU`,
but signed, prefixing `Sign(X)`
`StrT(X, M, N)` : pad `StrU(X, 1, N)` on left
with spaces to length `M+N+1`
`StrW(X, M, N)` : pad `StrS(X, 1, N)` on left
with spaces to length `M+N+2`

* the results exceed `M` leading digits if necessary

* `M, N` must not be negative

* `M, N` should be positive

* `M, N` zero may/will give deprecated format

* the effect of omitting `,M,N` is unspecified

* if the number `X` is too big for the method,
`e`-format is returned

* preferences for function `Sign()` may vary

`StrU` and `StrS` were re-implemented here on
2009-01-12, and since adjusted, obtaining the core `StrC` by
modifying `StrU`, in order to improve the behaviour of
`StrS` with non-numeric inputs.

*For StrS StrW, if X is slightly negative then
the returned string woll be -0.00 or similar. To avoid that, if
the value initially assigned to St is "0" then the
sign appended should be that corresponding to true zero. One can use
Sign(X*St) instead, or insert if (!+St) X = 0.*

If the number of digits needed is so large that the initial
`St` is in `e`-format, but `X` itself is not that
large, the result will be a [signed] digit string with the right
numerical value and no fractional part.
*One might replace ChrsTo(X, with
ChrsTo(String(X).replace(/^[ +-](\d+)$/, "$1.00"),; but
that would rarely be worthwhile.*

Note that the final paragraph tests `StrU` with the first
argument missing, or a simple Object, or an Array, or a
Date Object, or a Function.

There are more rounding functions,
`STRU STRS STRT STRW`, with test harness,
in Rounding 3.
They use a more flexible method.

For these, the intended range of M & N is from 0 upwards, though actual use of 0 for either is generally deprecated (M=N=0 gives a signed decimal point). Both M & N are otherwise unlimited, but M+N>16 is usually silly, as numbers are at best good to 15-16 significant figures.

To sign, integer part, point, N decimal places, where
`Math.floor(y)` does not give e-format (|y|<10^{21})
:-

N.B. *with N=2, "1.5555" gives "+1.56", "0.5555" gives "+0.56";
"0.0555" gives "+0.06", "0.0055" gives "+0.01", "0.0033" gives "+0.00",
"0" gives " 0.00". These are correct.*

To sign, M digits, or more if the value requires it (with leading
zeroes; if unwanted, put M=1; if always unwanted, remove
" `M,`" and "`j<M||`"), decimal point, N
decimal places :-

N.B. *with M=N=2, "1.5555" gives "+01.56", "0.5555" gives
"+00.56"; "0.0555" gives "+00.06", "0.0055" gives "+00.01", "0.0033"
gives "+00.00", "0" gives " 00.00". These are correct.*

See also `toExponential` above.

I would like to add a function that returns a string of chosen size.

New code is in Rounding 3, and this section may eventually be removed.

These are the functions now used across this site.

Round to N significant figures (returns a number) :-

For N significant figures, exponential format (returns a string) :-

Extend a number or a string to >= N decimals
(cannot test a string on this page) :-