in Libraries

Javascript Gaussian/Banker’s Rounding

Here’s a function for Gaussian/Banker’s Rounding in Javascript adapted from code written by Michael Boon at //boonedocks.net/.

This can be useful if you’re working with Microsoft languages such as VBScript, which use Banker’s Rounding by default in their Round function. Javascript has no built-in gaussian rounding and, instead, uses Arithmetic rounding. For more information on this, see Wikipedia’s article on rounding, specifically, the Round to Even section.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
    Adapted from <a href="//boonedocks.net/code/bround.inc.phps">//boonedocks.net/code/bround.inc.phps</a>
Provided under the GNU General Public License
    Contact me for use outside the bounds of that license
 
---------------------------------------------------------------
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
The GNU General Public License can be found at:
//www.gnu.org/copyleft/gpl.html
 
 
*/
<a href="//boonedocks.net/code/bround.inc.phps"></a>
Number.prototype.gaussianRound = Number.prototype.bankersRound = function bround(iDec) {
    return Math.gaussianRound ( this, iDec );
};
 
Math.gaussianRound = Math.bankersRound = function (dVal, iDec) {
 
// banker's style rounding or round-half-even
// (round down when even number is left of 5, otherwise round up)
// dVal is value to round
// iDec specifies number of decimal places to retain
 
var
    dFuzz=0.00001, // to deal with floating-point precision loss
    iRoundup=0, // amount to round up by
    iSign= dVal != 0.0 ? Math.floor ( dVal/ Math.abs( dVal ) ) : 1;
 
dVal=Math.abs(dVal);
 
// get decimal digit in question and amount to right of it as a fraction
dWorking = dVal * Math.pow ( 10.0, iDec + 1 ) -
    Math.floor ( dVal * Math.pow ( 10.0, iDec ) ) * 10.0;
 
iEvenOddDigit =
    Math.floor ( dVal * Math.pow ( 10.0, iDec) ) -
    Math.floor ( dVal * Math.pow ( 10.0, iDec-1 ) ) * 10.0;
 
if ( Math.abs ( dWorking - 5.0 ) < dFuzz)
    iRoundup= iEvenOddDigit & 1 ? 1 : 0; // even testing using bitwise and
else
    iRoundup= dWorking > 5.0 ? 1 : 0;
 
return iSign * ( ( Math.floor ( dVal * Math.pow (10.0,iDec ) ) + iRoundup )/ Math.pow(10.0,iDec) );
 
 
};