Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Close is the Javascript Math.Round to the C# Math.Round?

I know from reading this Stackoverflow question that the complier will look at your number, decide if the midpoint is an even or odd number and then return the even number. The example number was 2.5 which rounded to a 3. I've tried my own little experiments to see what happens, but I have yet to find any specifications about this, or even if it would be consistent between browsers.

Here's an example JavaScript snippet using jQuery for the display:

$(document).ready(function() {
    $("#answer").html(showRounding());
});

function showRounding() {
    var answer = Math.round(2.5);
    return answer;
}

This returns a '3'.

What I would like to know is this: How close is the rounding in JavaScript to the the C# equivalent? The reason I'm doing this is because I would like to take a JavaScript method that uses Math.Round and rewrite the same method into C# and would like to know that I would be able to get the same results after rounding a number.

like image 271
Chris Avatar asked Feb 03 '23 08:02

Chris


2 Answers

Here's the complete javascript specification for Math.round(x):

15.8.2.15 round (x) Returns the Number value that is closest to x and is equal to a mathematical integer. If two integer Number values are equally close to x, then the result is the Number value that is closer to +∞. If x is already an integer, the result is x.

  • If x is NaN, the result is NaN.
  • If x is +0, the result is +0.
  • If x is −0, the result is −0.
  • If x is +∞, the result is +∞.
  • If x is −∞, the result is −∞.
  • If x is greater than 0 but less than 0.5, the result is +0.
  • If x is less than 0 but greater than or equal to -0.5, the result is −0.

NOTE 1 Math.round(3.5) returns 4, but Math.round(–3.5) returns –3.

NOTE 2 The value of Math.round(x) is the same as the value of Math.floor(x+0.5), except when x is −0 or is less than 0 but greater than or equal to -0.5; for these cases Math.round(x) returns −0, but Math.floor(x+0.5) returns +0.

The C# Language Specification does not stipulate any particular rounding algorithm. The closest thing we have is the documentation for .NET's Math.Round. From that, you can see that some of the javascript cases don't apply (Math.Round only handles decimals and doubles, not infinity), and the method's overloads give you a lot more control over the result - you can specify the number of fractional digits in the result and the midpoint rounding method. By default, Math.Round uses 'banker's rounding' (to even).

like image 77
Jeff Sternal Avatar answered Feb 06 '23 01:02

Jeff Sternal


ECMAScript's rounding is basically naive asymmetric rounding (with added checks for +-Infinity). WRT porting your JavaScript code to C# you're probably best to avoid .NET's Math.Round (as it is always symmetric) and use Math.Floor instead:

double d = -3.5d;
double rounded = Math.Floor(d + 0.5); // -3 matches JavaScript's Math.round

That is, if you want strict emulation of ECMAScript's Math.round.

like image 45
Crescent Fresh Avatar answered Feb 06 '23 00:02

Crescent Fresh