Quiz: Can you count on JavaScript?
Know your `parseInt` from `parseFloat`?
Welcome to my JavaScript Numbers Challenge!
This quiz will test your knowledge all things Numbers in JS, parseInt
, parseFloat
, and BigInt
too!.
We’ll cover parsing numeric expressions - in varying bases, handling floating-point precision, and understanding the quirks of JavaScript’s number system.
It’s only numbers, how hard can it be? 🤓
Warm-up
parseInt(" 123456.00")
The parseInt
function ignores spaces and parses the initial sequence of digits as an integer. Here, it stops at the decimal point, so only 123456
is returned.
Parsing
parseInt("123,456.00")
Generally speaking, parseInt
stops parsing when it encounters a non-numeric character. Here, it stops at the comma, so only 123
is returned.
Math
0.1 + 0.2 === 0.3
Due to floating-point precision errors, 0.1 + 0.2
does not exactly equal 0.3
. Due to the way floating-point numbers are stored in memory, the result is 0.30000000000000004
. The IEEE 754 standard for handling floating-point arithmetic is the culprit, it can’t represent some numbers exactly. This is a common issue in all programming languages. Eventually you’ll run into a infinitely repeating decimal, and no matter the language - the computer simply has to stop chasing infinitely repeating digits.
Some languages like Python and Java have Decimal
or BigDecimal
to handle this, but it’s not built into JavaScript. You can use libraries like big.js
or decimal.js
to handle these cases.
(Note: Some languages are designed to handle fractions, imaginary numbers, etc at a higher logical level, preserving literal expressions. But they still have to deal with the same floating-point precision issues at the hardware level.)
Overflowing Numbers
Number.MAX_VALUE * 2
Since Number.MAX_VALUE
is the largest representable regular number in JavaScript, going over its limit will quickly overflow - basically you might see meaningless results. Multiplying it by 2
results in Infinity
.
Ya know, JavaScript be like that sometimes.
Formatting
What might this do?
5..toFixed(2)
.toFixed(2)
returns a string representation of 5
with two decimal places, so the result is "5.00"
.
The double dot (5..toFixed(2)
) is a ‘trick’ to access Number Literals’ Object Model.
Comparing types
parseInt("42") === parseFloat("42")
In JavaScript, both parseInt
and parseFloat
will interpret the string "42"
as the number 42
. Therefore, the comparison parseInt("42") === parseFloat("42")
evaluates to true
. While parseInt
stops parsing at the first non-digit character, parseFloat
continues parsing until it encounters a character that is not part of a floating-point number. However, since there are no decimal points or other non-numeric characters in "42"
, both functions return the same value.
Based
What will this work out to?
parseInt("0x2A") === parseInt("2a", 16)
Any input string that begins with 0x
is auto-magically treated as a hexadecimal (radix 16
).
It is therefore equivalent to passing a radix of 16. So, parseInt("0x2A")
is the same as parseInt("2a", 16)
. (It’s case insensitive.)
Based
What’s the dealio here?
parseInt('0xFF', 16)
parseInt
with a hexadecimal (16
) base converts "FF"
to 255
in decimal. You may have seen this in CSS RGB/Hex color codes.
Number[]
[24, 'One', 42].map(parseInt)
The second argument to parseInt
(the radix) aligns with the array methods’ index
argument. This leads to unexpected results, as parseInt("One", 1)
returns NaN
due to the invalid input.
The first element, 24
, is parsed as 24
in base 0 (auto-detect), so it remains 24
. The second element, 'One'
, is parsed as NaN
in base 1. The third element, 42
, is parsed using base 2. In base 2, '42'
is NaN
, so the result is [24, NaN, NaN]
.
This is a common gotcha with parseInt
and map
. If you want to parse an array of strings to numbers, the only safe “built-in” method is .map(Number)
or adding a callback/enclosure .map(x => parseInt(x, 10))
.
Number[]
[24, 'Twenty1', 0o42].map(Number)
Number
converts values to a numeric type more strictly than parseInt
. Here, 'Twenty1'
becomes NaN
, while 0o42
is recognized as an octal literal and converted to 34
.
Parsing
What will be the result of this code?
console.log(parseInt(null), Number(null))
parseInt
coerces the input to a string, so null
becomes "null"
. Since "null"
has no valid base-10 characters (regular numbers) it will return NaN
.
Number(null)
returns 0
. because JS likes to keep you on your toes.
Why? Well, I might go deeper if there’s interest.
Parsing
What will be the result of this spell?
parseInt(null, 36)
Since parseInt
always coerces the input to a string, null
becomes string "null"
.
In base 36 (hexatrigesimal, if you’re keeping track), the string "null"
represents 1112745
.
The sequential values of nulk
, null
, and nulm
are respectively 1112744
, 1112745
, and 1112746
in base 36.
Comparison Table
Function | parseInt | parseFloat | Number | BigInt |
---|---|---|---|---|
Ignores Whitespace | ✅ | ✅ | ✅ | ✅ |
.map(FN) | ❌ | ☑️ | ✅ | ✅ |
Supports Radix Arg | ✅ | ❌ | ❌ | ❌ |
Binary/Octal/Hex literals | ✅ | ❌ | ✅ | ✅ |
Invalid chars 42 oh no | 42 | 42 | NaN | SyntaxError |
How did you do? 🧐
Are you looking for a rest after so much binary?
Pftt, remember: break after skills!
Hit my gym to crush some more challenges! 💪