logo To Foot
© J R Stockton, ≥ 2007-06-13

JavaScript Rounding 3.

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

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

Rounding a Number to Decimal Places

Rounding to a stated number of decimal places implies conversion to String. Such rounding is often required for the display of results.

The code here separates the integer and fractional parts of the input. It adds 1.0 to the fractional part to ensure that it has sufficient digits, multiplies it by a power of 10, rounds it to integer, converts it to String, and combines the parts.

Arguments

The first argument X gives the value to be converted; it is presumed to be treatable as a Number.

M is the minimum number of characters (other than sign) to precede the decimal point (values less than 1 give results as for 1), and N is the number of digits to follow it. Since they are usually supplied as literals, they are not checked.

Functions CORE, IntFrc, NearHalf

JavaScript rounding function CORE(X, N) transforms the numerical value of X to a string of the form digit(s) - Point - N digits, using a method that I don't recall seeing elsewhere. The rounded result must be non-negative. No specific allowance is made for unreasonable inputs.

For test, it is shown below with an auxiliary function IntFrc which provides various choices for the detail of the rounding. The call of IntFrc should normally be replaced by code with effect similar to that of one of the cases of IntFrc.

When used with IntFrc cases 1 & 2, it matches the earlier functions of c.l.j newsgroup FAQ 4.6, Web page js-round.htm#GC and file include1.js. With cases 3 & 4, it gives Bankers' Rounding.

Where IntFrc uses |0 the fractional part of the final result must not exceeed 9 digits.

Function NearHalf can be used so that near-halfway cases are treated as exact half-way cases.

Functions STR*, NOGO

Wrapping function STRU(X, M, N) transforms the numerical value of X to a string of the form M digits - Point - N digits.

Wrapping function STRT(X, M, N) transforms the numerical value of X to a string of the form M places - Point - N digits.

They are for unsigned results; functions STRS STRW are further wraps for signed results.

Internally-called function NOGO detects inappropriate values of X so that they may be returned verbatim but padded to length.

The least effective value of M is 1; N should exceed 0, but not 14.

N.B. Functions STR* are analogous to Str* but results may not match exactly.

Exactness

Argument X itself may be inexact. But the only operation within CORE which may be inexact is the multiplication by 10N; and that will be exact if int is over about 5N. The routines calling CORE are exact. Function IntFrc should be exact. CHECK.

Code and Test

  CaseNo = Rounding Type :
  0=Trunc, 1=Round, 2=Alt Round, 3=Simple Bankers',
  4=Better Bankers', 5=Double-round, 6=Ceil, 7=Statistical, others?
  X = Expression to round
  M = minimum characters before Point
  N = digits after Point (integer)
Result strings :
CORE(X,    N)  +
STRU(X, M, N)  +
STRT(X, M, N)  +
STRS(X, M, N)  ±
STRW(X, M, N)  ±

The value of X should be a Number, but other types may be converted to Number.

The value X = null is treated as zero. The values Infinity NaN & undefined are shown as such. Those can be supplied for X (test input uses eval).

Effects of Input Rounding Errors

If the earlier calculation was such that, in exact arithmetic, X would have been some form of decimal "round number", but may actually be slightly in error, then one may need to compensate.

The magnitude of such rounding errors will generally be a few parts in 253 of X.

For simple ceil, round, floor one would respectively add, add, subtract a small amount; perhaps a tenth or a hundredth of a final least digit.

Near-Zero Inputs

For most cases in IntFrc a slightly negative input will naturally round to zero.

General Previous Rounding Errors

To get nominal rounding for cases where previous accumulated rounding errors may have made X differ from an ideal half-way value, code may give special treatment to any values of frc which are sufficiently near to a half-integer, as in Better Bankers' and Double-round. For large X or N the comparison in NearHalf may need adjustment.

Similar code may be needed when using unsigned ceil & floor - NearHole() ??. OTOH, first adding/subtracting a small amount should suffice.

Bankers' Rounding

Bankers' Rounding (BR) of a value half-way between the two rounded possibilities gives the one with an even final digit.

BR makes no sense except where the value is exact, or is deemed exact, in the (even) base in which the rounding is done. Then, "half-way" is always possible and meaningful.

A requirement for BR may be imposed regardless of whether it makes sense in the circumstances.

Some routines from include1.js are used; see my Include Files.

The code has not necessarily been optimised.

A Number to a Integer Number

BR of a Number to the nearest integer Number is meaningful, and can be done by code that treats half-integers specially :-

   

A Pounds String to Exact Pence

If a Pounds value is represented as a decimal string, BR to pence is always meaningful and can be done using the string representation for decisions. When carry propagation may be needed it seems simplest to recurse with a new String in which the Carry has been done by arithmetic.

The code is for input strings in normal fixed-point form, and not for values using E-format.

   

Trailing zeroes after the round-off point are here treated as a small digit.

Rounding a Number to Given Precision

This replaces a part of Rounding 1, and that section may eventually be removed.

The chief aim is to present results of rounding the Number X to N significant figures, and to use in result strings the preferred practices of having a digit each side of a decimal point and not suppressing meaningful trailing zeroes.

See also toExponential in Rounding 1.

See also in Rounding 1 for the StrU family of display functions with given absolute resolution.

NOTE :- If too many figures are demanded, existing rounding errors will show, and arithmetic may introduce others. JavaScript itself supports only up to 15 significant figures.

NOTE :- The new routines are now used on this site.

Code for Testing

Old Code

These showed problems, for example with some exact powers of ten, and are now replaced.

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

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

Current Code

The fixed nine-letter names are used across this site; the twelve-letter names are those of the function declarations assigned to them, and could change.

New Code

Shared Functions

Functions LZ StrU Sign are imported from file include1.js; see Include Files.

For a three-digit exponent, use LZZ and for no leading zero omit LZ .

By Arithmetic

Common

Note : N multiplications or divisions by 10 may not give exactly the same as one by 10N.

To a Number
To a Fixed-Point String
To a Float-Point String

By String Manipulation

Doing it *starting* with X.toString() then using string operations as far as possible :-

Common

The output of Tri_Part is used to generate other formats.

To a Float-Point String
To a Fixed-Point String

Test Form

   

The input may be any expression, such as 1/-0

Utilities

Cent Number To Euro String

Adapted from Evertjan. Rounding of 0.5c is JavaScript normal, towards plus infinity.

   

Truncation

Truncation should be possible in the same manner as Rounding.

Also consider, for one decimal place or more,

Leading Zeroes to Leading Spaces

Preserving number and moving sign :-

. .

Unicode "\u20AC" is the Euro sign, "€" or "€"; "\u00A3" is the Pound sign, "£". Function LZS() can process more than one number in a string.

Extending Left to Overall Length

For extending to the left, see ChrsTo() as above and for simple cases LZ(), LZZ() as in JavaScript Maths.



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