views:

2838

answers:

4

Edit: To clarify, the problem is how to round a number to the nearest integer. i.e. 0.5 should round to 1 and 2.5 shoud round to 3.

Consider the following code:

<html><head></head><body style="font-family:courier">
<script>
for (var i=0;i<3;i++){
   var num = i + 0.50;
   var output = num + " " + Math.round(num) + " " + num.toFixed(0);
   var node = document.createTextNode(output);
   var pElement = document.createElement("p");
   pElement.appendChild(node);
   document.body.appendChild(pElement);
}
</script>
</body></html>

In Opera 9.63 I get:

0.5 1 0

1.5 2 2

2.5 3 2

In FF 3.03 I get:

0.5 1 1

1.5 2 2

2.5 3 3

In IE 7 I get:

0.5 1 0

1.5 2 2

2.5 3 3

Note the bolded results. Does this mean that toFixed(0) should be avoided?

+2  A: 

Edit: To answer your edit, use Math.round. You could also prototype the Number object to have it do your bidding if you prefer that syntax.

Number.prototype.round = function() {
  return Math.round(this);
}
var num = 3.5;
alert(num.round())

I've never used Number.toFixed() before (mostly because most JS libraries provide a toInt() method), but judging by your results I would say it would be more consistent to use the Math methods (round, floor, ceil) then toFixed if cross-browser consistency is what you are looking for.

tj111
+1  A: 

Instead of toFixed(0) use Math.ceil() or Math.floor(), depending on what is required.

Grant Wagner
A: 

It definitely seems that way, if you're getting inconsistent answers.

I can only guess that your intent with usin toFixed(0) is to turn a decimal number into an integer, at which point I recommend Math.floor(). There's a bit more discussion on the best way to do so in this question.

Daniel Lew
+1  A: 

I think FF is doing the right thing with toFixed, since step 10 below says "If there are two such n, pick the larger n."

And as Grant Wagner said: Use Math.ceil(x) or Math.floor(x) instead of x.toFixed().

Everything below is from the ECMAScript Language Specification:

15.7.4.5 Number.prototype.toFixed (fractionDigits)

Return a string containing the number represented in fixed-point notation with fractionDigits digits after the decimal point. If fractionDigits is undefined, 0 is assumed. Specifically, perform the following steps:

1. Let f be ToInteger(fractionDigits). (If fractionDigits is undefined,
   this step produces the value 0).
2. If f < 0 or f > 20, throw a RangeError exception.
3. Let x be this number value.
4. If x is NaN, return the string "NaN".
5. Let s be the empty string.
6. If x ≥ 0, go to step 9.
7. Let s be "-".
8. Let x = –x.
9. If x ≥ 10^21, let m = ToString(x) and go to step 20.
10. Let n be an integer for which the exact mathematical value of
    n ÷ 10^f – x is as close to zero as possible. If there are two
    such n, pick the larger n.
11. If n = 0, let m be the string "0". Otherwise, let m be the
    string consisting of the digits of the decimal representation
    of n (in order, with no leading zeroes).
12. If f = 0, go to step 20.
13. Let k be the number of characters in m.
14. If k > f, go to step 18.
15. Let z be the string consisting of f+1–k occurrences of the
    character ‘0’.
16. Let m be the concatenation of strings z and m.
17. Let k = f + 1.
18. Let a be the first k–f characters of m, and let b be the
    remaining f characters of m.
19. Let m be the concatenation of the three strings a, ".", and b.
20. Return the concatenation of the strings s and m.

The length property of the toFixed method is 1.

If the toFixed method is called with more than one argument, then the behaviour is undefined (see section 15).

An implementation is permitted to extend the behaviour of toFixed for values of fractionDigits less than 0 or greater than 20. In this case toFixed would not necessarily throw RangeError for such values.

NOTE The output of toFixed may be more precise than toString for some values because toString only prints enough significant digits to distinguish the number from adjacent number values. For example, (1000000000000000128).toString() returns "1000000000000000100", while (1000000000000000128).toFixed(0) returns "1000000000000000128".

some