logo To Foot
© J R Stockton, ≥ 2007-04-04

JavaScript Rounding 1.

No-Frame * Framed Index * Frame This
Links within this site :-

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

Rounding a Number to a Number

Rounding to an Integer

The standard methods of Math are not always adequate.

To integer, towards zero :-

To integer, towards zero, for |X| < 231 :-

General Rounding

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) :-

Formatting a Number to a Decimal String

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).

The Status Quo

The Default Conversion

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

The Needs

Options that should be provided include whether :-

Sign Functions

To return a sign character; alternatives may be preferred :-
 function Sign(X) { return (X<0 ? '-' : '') }
 function Sign(X) { return (X>0 ? '+' : X<0 ? '-' : ' ') }

A definite indication of positive sign, of a fixed length, may be needed. This is used here :-

The Native Methods

JavaScript should provide reliable native number-output routines with the power of those of more mature languages. There are more routines in MS JScript 5.5.

toString

Of itself, method Number.toString() is not directly useful in this context, since the format is variable; it is the same as for the "automatic" conversions such as in new String(number). However, all versions have it.

toFixed

The JavaScript internal method Number.toFixed() is only available in later browsers, and even then will not always be suitable. The internal method may err : try 0.07 and 1.129 for possible truncation; try toFixed(0) for 0.50 to 0.94 or to 0.999...

" ... bug in Number.toFixed(), namely that for values n in {(-0.94,-0.5], [0.5,0.94)}, n.toFixed(0) returns 0 instead of -1 or 1."

Apparently, (0.0625).toFixed(1) gives 0.0.

A Replacement

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 include1.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 Replacement

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.

toExponential, toPrecision

There may also be Number.toExponential() and Number.toPrecision() - the latter uses either the former or Number.toFixed, as necessary. If the browser knows them, untested tests follow.

Using the Native Converter, Indirectly

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

In Rounding 2.

Satisfactory Conversions to String

In Rounding 2.

Another Conversion to String

In Rounding 2.

Good Conversions to String

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.

These seem to be good functions, all returning strings; the input X is expected, but not obliged, to be of type Number :-

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
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)
StrT(X, M, N) : pad StrU(X, 1, N) on left with spaces to length 1+M+1+N
StrW(X, M, N) : pad StrS(X, 1, N) on left with spaces to length 1+M+1+N
* M, N must not be negative
* M, N should be positive
* M, N zero may/will give deprecated format
* the results exceed M leading digits if necessary
* if the number X is too big for the method, e-format is returned
* preferences for function Sign() may vary

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

Other Good? Conversions to String

In Rounding 2.

Converting Ab Initio to String

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|<1021) :-

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.

Rounding to N Significant Figures

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.

To a Number

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

To a String

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

Extending Right to N Decimals

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


JavaScript Rounding   0, 2, 3.
Home Page
Mail: no HTML
© Dr J R Stockton, near London, UK.
All Rights Reserved.
These pages are tested mainly with MS IE 6 and W3's Tidy.
This site, http://www.merlyn.demon.co.uk/, is maintained by me.
Head.