Skip to content

Instantly share code, notes, and snippets.

@darkterminal
Forked from quant61/Javascript_toNumber.md
Created January 10, 2023 11:57
Show Gist options
  • Save darkterminal/3d244cd61e2860035f6e5926d9cdd2ec to your computer and use it in GitHub Desktop.
Save darkterminal/3d244cd61e2860035f6e5926d9cdd2ec to your computer and use it in GitHub Desktop.
conversion to number in javascript

Some notes about conversion to number in javascript

javascript has lots of methods to convert any value to number

  • all methods could be divided into 2 groups: string and native methods
    • String methods are parseInt and parseFloat
    • Native mathods are Number and Math methods

all native methods behave the same way, sometimes with additional transform

for converting to Number best choices are parseFloat and Number to convert to integer you can use parseInt and Math.round

Number("13.2") //13.2
parseFloat("13.2") //13.2
parseInt("13.2") // 13
Math.round("13.2") // 13

they both work well for valid number strings but have different behavior on some values

  • trailing garbage
// string funcions read valid part and ignore trailing garbage
parseFloat("14.5px") // 14.5
parseInt("14.5px") // 14
// native methods treat this values as invalid
Number("14.5px") // NaN
Math.round("14.5px") // NaN
  • integer round
// parseInt just ignores trailing chars so it round number to near to zero
parseInt("12.7") // 12
// but Math has 3(4 in ES6) functions with different behavior
Math.round("12.7") // 13
Math.round("12.3") // 12
Math.floor("12.9") // 12
Math.ceil("12.1") // 13
  • empty string
parseFloat("") // NaN
parseInt("") // NaN
Number("") // 0
Math.round("") // 0
  • native javascript values
// but native functions have better support for nonstring values
[null, false, true].map(parseFloat) // [NaN, NaN, NaN]
[null, false, true].map(Number) // [0, 0, 1]

for Date parseInt and parseFloat return NaN, but Number return milliseconds from 1970-01-01 UTC(unixtime multiplied by 1000)

parseInt also can be also used for converting from nonstandard bases(from 2 to 36)

parseInt("file", 25) //246164
(246164).toString(25) // "file"
  • parseInt and Number also support hex literal, but parseFloat doesn't
parseFloat("0xff") // 0
parseInt("0xff") // 255
Number("0xff") // 255
  • objects
// if object has both toString and valueOf methods, string functions will use toString, native will use valueOf
var testObject = {
  toString: function(){return "13"},
  valueOf: function(){return "42"}
};

parseFloat(testObject) // 13
parseInt(testObject) // 13
Number(testObject) // 42
+testObject // 42
Math.round(testObject) // 42
testObject * testObject // 1764
testObject + testObject // "4242"

another ways of converting

  • operators
+"42" // 42
"42" - 0
"42" * 1
"42" / 1
// but `+` means string concat
"42" + 0 // "420"
// `-= 0`, `*=1`, `/=1`, ES6:`**1` can be also used to prevent writing variable's name twice  
very.long.path.to.veryLongName.subObject.param -= 0;
  • 32-bit integer conversion
// sometimes 32-bit conversion to integer is used

value|0
~~value

// invalid values are converted to 0

Number("a string") // NaN
"a string"|0 // 0

// but it truncates all higher bits in big numbers

1e10 | 0 // 1410065408
// look at both number in hex
(1e10).toString(16) // "2540be400"
(1410065408).toString(16) // "540be400"
(0xa9876543210 | 0) === (0x76543210) // true

in ES6 there's also Math.fround function to convert to float32

Math.fround("1.3") // 1.2999999523162842

extra + fun + dumb functions

// convert to n-bit unsigned integer for any n from 1 to 31:
value & ((1<<n)-1)

// just for fun
value % Infinity // but Infinity % Infinity is NaN
Math.pow(value, 1)
// in ES6 there's also
value ** 1;

// sometimes eval and JSON.parse work too
eval("42") // 42
JSON.parse("42") //42
// but eval is unsafe
eval("location.href='http://spam.site'")
// JSON.parse can return other types
JSON.parse('{"key":"value"}') // Object {key: "value"}
// or throw an error
{
  JSON.parse("invalid");
  // the code below will not be called
}

/** 
  * you can also convert to other number types through typed arrays
  * @param value - any value
  * @param arrayClass - typedArray class
  */
function toTyped(value, arrayClass){
  var array = new arrayClass(1);
  array[0] = value;
  return array[0];
}
toTyped("1234", Int8Array) // -46
toTyped("1234", Uint8Array) // 210
toTyped("1234", Uint8ClampedArray) // 255

toTyped("1.3", Float32Array) // 1.2999999523162842
toTyped("1.3", Float32Array) === "1.3" //false
toTyped("1.3", Float32Array) === Math.fround("1.3") //true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment