Skip to content

Instantly share code, notes, and snippets.

@a1mersnow
Created March 30, 2019 02:38
Show Gist options
  • Save a1mersnow/d2747f8b5f40e3ad3968050fb70ed24a to your computer and use it in GitHub Desktop.
Save a1mersnow/d2747f8b5f40e3ad3968050fb70ed24a to your computer and use it in GitHub Desktop.
string to number without using Number or parseFloat
/**
* @param {string} str
*/
function str2num (str) {
const [m, e = ''] = str.split('e')
const [i, f = ''] = m.split('.')
let result = 0
// handle int
let sign = 1
for (let x of i) {
if (x === '+') {
continue
} else if (x === '-') {
sign *= -1
continue
} else {
result *= 10
result += c2n(x)
}
}
// handle fraction
if (f) {
result += str2num(f) / (10 ** f.length)
}
// handle exponent
if (e) {
let exponent
let sign = 1
if (e[0] === '-') {
sign = -1
exponent = str2num(e.slice(1))
} else if (e[0] === '+') {
exponent = str2num(e.slice(1))
} else {
exponent = str2num(e)
}
if (sign === -1) {
result /= 10 ** exponent
} else {
result *= 10 ** exponent
}
}
// handle sign
result *= sign
return result
}
function c2n (char) {
const n = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][char]
if (n == null) throw new Error(`unknown char: "${char}"`)
return n
}
function assert (input) {
let output = str2num(input)
let expect = Number(input)
if (output !== expect) {
throw new Error(`input ${input}, got ${output}, while expect ${expect}`)
}
}
void function test () {
assert('13.4e-7')
assert('.4e+7')
assert('-.2e+1')
assert('+.6e+0')
assert('0')
assert('-0e-0')
assert('0e0')
assert('123')
assert('2e1')
assert('2e-0')
assert('.1')
console.log('All right.')
}()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment