2

I found this code in a SO answer as a way to truncate a number into an integer in Javascript:

var num = -20.536;
var result = num | 0;
//result = -20

Is this a valid way to truncate a number in Javascript, or it is some kind of hack? Why does it works only with numbers less than 2147483647?

Community
  • 1
  • 1
Guillermo Gutiérrez
  • 17,273
  • 17
  • 89
  • 116
  • 3
    [The number 2,147,483,647 is also the maximum value for a 32-bit signed integer in computing.](http://en.wikipedia.org/wiki/2147483647) – epascarello Jan 15 '14 at 20:24
  • Yes number must be less than 2.147.483.647 because integer and floating point ranges overlaps but they're not the same. With Math.floor() you truncate number to its integer part but you still have a floating point. – Adriano Repetti Jan 15 '14 at 20:24
  • 1
    javascript stores all numbers as double by default. – T McKeown Jan 15 '14 at 20:25
  • Amazing, it has it's own Wikipedia page! – Guillermo Gutiérrez Jan 15 '14 at 20:26
  • 1
    @GuillermoGutiérrez even [36](http://en.wikipedia.org/wiki/36) has its own Wikipedia page! LOL – Adriano Repetti Jan 15 '14 at 20:27
  • @TMcKeown no, integer and floating point are different things in JavaScript. They follow different rules in many parts of the Standard. – Adriano Repetti Jan 15 '14 at 20:28
  • @Adriano, no double is the default: http://ecma262-5.com/ELS5_HTML.htm#Section_8.5 – T McKeown Jan 15 '14 at 20:30
  • Guillermo can you do this: var num = new Number(reallyBigNumber); – T McKeown Jan 15 '14 at 20:31
  • @TMcKeown, it seems to support very big numbers as floating points, right? – Guillermo Gutiérrez Jan 15 '14 at 20:35
  • 1
    @TMcKeown it doesn't matter how a number is stored! It's an implementation detail. After it has been _converted_ (let me use this word) to a 32 bit integer then it has not its original precision (and it has been truncated to 32 bit signed integer values range). Search through the standard for ToInteger() or ToInt32()...you'll see in how many parts a floating point must be converted. – Adriano Repetti Jan 15 '14 at 20:36
  • yes, i posted this as my answer... =) please up vote. I tested on jsfiddle, working. – T McKeown Jan 15 '14 at 20:37
  • ok I agree with that. – T McKeown Jan 15 '14 at 20:37
  • On Firebug's console, it gives me: `(new Number(-20.536)).toString() -> "-20.536"` – Guillermo Gutiérrez Jan 15 '14 at 20:40
  • 1
    It is a "valid hack" ;) ..but I prefer Math.floor for the reasons given by Guffa. If you're interested in performance, bitwise or looks to be faster than parseInt(), but roughly as fast as Math.floor() - check it: http://jsperf.com/math-floor-vs-math-round-vs-parseint/55 . – rom99 Jan 15 '14 at 20:40
  • 1
    @GuillermoGutiérrez, i thought you were just having a problem with the size. Sorry, I didn't realize you were trying to show as int. Math.floor() and parseInt() will do the trick as already stated. – T McKeown Jan 15 '14 at 20:43
  • Ah, ok, thanks @TMcKeown. Good to know that, though :) – Guillermo Gutiérrez Jan 15 '14 at 20:45

3 Answers3

5

That method works by implicitly converting the number to a 32-bit integer, as binary operators use 32-bit integers in their calculations.

The drawbacks of that method are:

  • The desired operation is hidden as an implicit effect of the operator, so it's not easy to see what the intention of the code is.

  • It can only handle integers within the range of a 32-bit number.

For any regular case you should use the Math.floor or Math.ceil methods instead, it clearly shows what the intention of the code is, and it handles any number within the precision range of a double, i.e. integers up to 52 bits:

var num = 20.536;
var result = Math.floor(num); // 20

var num = -20.536;
var result = Math.ceil(num); // -20

There is no round-towards-zero method in Javascript, so to do that you would need to check the sign before rounding:

var result = num < 0 ? Math.ceil(num) : Math.floor(num);
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 1
    `Math.floor()` will however not truncate negative numbers! `Math.floor(-20.2324) === -21` – basilikum Jan 15 '14 at 20:31
  • @basilikum: Yes, I realised that and added examples to show what to use for positive and negative numbers, and an option that works for both. – Guffa Jan 15 '14 at 20:34
  • @Guffa "There is no round-towards-zero method in Javascript" - `parseInt` doesn't count? – Matt Jan 15 '14 at 20:43
  • @Matt: No, it doesn't count. :) It's not a method for rounding, it's a method for parsing. If you use it for rounding, you will convert the number to a string, then parse it to a number, so it's quite inefficient. Also, it hides the intention of the code, as you really don't want to parse anything. – Guffa Jan 15 '14 at 21:44
  • @Guffa Agreed that `parseInt` is not a method for **rounding**, but the OP did ask for a method for **truncating** which is no more a mathematical operation than a string operation, for which `parseInt` would be appropriate. Anyways, this is just semantics; cheers. – Matt Jan 15 '14 at 22:39
2

Use Javascript's parseInt like so:

var num = -20.536;
var num2int = parseInt(num);

return num2int; //returns -20

Tada! num is now an int with the value of -20.

mjkaufer
  • 4,047
  • 5
  • 27
  • 55
2

If you use parseInt you can go from -2^53 to +2^53:

parseInt(-20.536) // -20

parseInt(9007199254740992.1234) // 9007199254740992

Why +/- 2^53? This is because JavaScript uses a 64-bit representation for floating point numbers, with a 52-bit mantissa. Hence all integer values up to 2^53 can be represented exactly. Beyond this, whole numbers are approximated.

Matt
  • 20,108
  • 1
  • 57
  • 70