5 ms·
round = function (num) { return +num + (~~num === num) * .5; }; What does ~~num do?
by pedrokost 16y ago
round = function (num) {
return +num + (~~num === num) * .5;
};
What does ~~num do?
- weego 16y agoit will round toward zero
- teamonkey 16y ago~ is bitwise NOT. For a number it returns the ones complement: ~N = -(N+1) So ~~num I think would return the original value. The only reason I can see would be to coerce it into some kind of number type.
- grayrest 16y agoBitwise operations coerce the value to a int32. If a value cannot be reasonably coerced to an int (e.g. 'foo'), you get zero. It's basically the same as parseInt(x,10) but is generally faster, you don't need to remember the radix, and you don't get NaN. The downside is that trying to coerce numbers outside int32 will give incorrect answers. The other way to write it is 0|num which has the advantage of only applying one bitwise op. These tend to crop up most often in graphics oriented libraries.
- euroclydon 16y agoThanks. Anything quicker than parseFloat?
- grayrest 16y agoYou'd have to bench it, but the only thing I could think of that'd be faster is the standard +num coercion that's also used in the code snippet. Unfortunately, that does generate NaNs. Edit: Double checked the spec (it's quite readable) and the main difference is that + will coerce ignoring whitespace while parseFloat will ignore leading whitespace and parse leading digits. E.g. var x = '1.23foo'; parseFloat(x) is 1.23; +x is NaN. Neither looks like it should be faster than the other.
- euroclydon 16y agoWhat exactly does this function do? I tried it: round("2.2") -> 2.2 round(2.2) -> 2.2 round("2.6") -> 2.6 round(2.6) -> 2.6
- endtime 16y agoIf num is an integer, it returns num + 0.5; otherwise it just returns num. I don't see why this is called 'round' or why it would be particularly useful behavior, so it's probably a bug.
- mryall 16y agoI'm pretty sure it's to work around a difference in SVG and VML. In SVG, a one-pixel line rendered at an integral coordinate (like x=1) will render half-half on either side of that value, resulting in a blurry two-pixel-wide line. VML renders a one-pixel line in this case, automatically colouring the pixel(s) between x=1 and x=2. Raphaël adds 0.5 to the values in SVG in order to make one-pixel-wide lines render as a single pixel instead of two.
- endtime 16y agoOh, cool, thanks for explaining that.