See "About This JavaScript Site" in JavaScript Index and Introduction.
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.
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.
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.
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.
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.
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).
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.
For most cases in IntFrc a slightly negative input will naturally round to zero.
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 (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.
BR of a Number to the nearest integer Number is meaningful, and can be done by code that treats half-integers specially :-
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.
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.
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) :-
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.
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 .
Note : N multiplications or divisions by 10 may not give exactly the same as one by 10N.
Doing it *starting* with X.toString() then using string operations as far as possible :-
The output of Tri_Part is used to generate other formats.
Adapted from Evertjan. Rounding of 0.5c is JavaScript normal, towards plus infinity.
Truncation should be possible in the same manner as Rounding.
Also consider, for one decimal place or more,
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.
For extending to the left, see ChrsTo() as above and for simple cases LZ(), LZZ() as in JavaScript Maths.