java parseint(12.0),如何实现一个parseInt

如何实现一个parseInt

function(string, [radix]) {}

如果string不为字符串类型, 则先将string转化为字符串类型

string会忽略前后的空白

依次解析字符, 如果字符不是指定基数中的字符( 例如:2进制中的3、 10进制中的'f' )则停止解析( 首字符为'+'或'-'时除外 ), 返回已经解析好的整数

如果无法解析为整数, 则返回NaN

radix 默认值不为10, 在radix为undefined、0或者没有指定时, 做以下处理

如果string以'0X'或'0x'开头时, 基数为16

如果string以'0'开头时, 基数为8或者10(每个浏览器的具体实现不同, es5规定此时为10)

如果string以其他任何字符开头时, 基数为10

radix的范围为2-36

不考虑进制radix

代码实现

const _parseInt = (str, radix) => {

if (typeof str !== 'string') str = String(str)

str = str.trim()

const regex = /^(?[+|-]*)(?d+)/

if (!regex.test(str)) return NaN

const groups = str.match(regex).groups

radix = 10

const arr = groups.num.split('')

const len = arr.length

let result = 0

for(let i = 0; i < len; i++) {

const num = arr[i] * Math.pow(10, len - i - 1)

if (isNaN(num)) break

else result += num

}

return result * (groups.fuhao === '-' ? -1 : 1)

}

测试用例

const assert = require('assert')

assert.strictEqual(_parseInt(null), NaN)

assert.strictEqual(_parseInt('0e0'), 0)

assert.strictEqual(_parseInt('08'), 8)

assert.strictEqual(_parseInt(0.0000003), 3)

assert.strictEqual(_parseInt(0.00003), 0)

assert.strictEqual(_parseInt(-0.0000003), -3)

assert.strictEqual(_parseInt('6.022e23'), 6)

assert.strictEqual(_parseInt(6.022e2), 602)

考虑radix

代码实现

const _parseInt = (str, radix) => {

// 不为string类型先转化为string 类型

if (typeof str !== 'string') str = String(str)

// 删除首尾空白

str = str.trim()

// 正则匹配[+|-]?[0]?[Xx]?[0-9a-fA-F]+

const regex = /^(?[+|-]*)(?[0]?[Xx]?)(?[0-9a-fA-F]+)/

// 无法匹配返回NaN

if (!regex.test(str)) return NaN

// 匹配出符号、进制、数字三个分组

const groups = str.match(regex).groups

// radix的有效范围为 2-36

if (radix && (radix < 2 || radix > 36)) return NaN

// 如果没有指定radix, radix 会有以下默认值

if (!radix) {

if (groups.radix.toUpperCase() === '0X') radix = 16

else if (groups.radix === '0') radix = 8

else radix = 10

}

// 挨个字符串解析,如果遇到无法解析时则停止解析,返回已经解析好的整数

let splitArr = groups.num.split('')

const arr = []

for(let i = 0; i < splitArr.length; i++) {

// 根据charCode来做转行为实际数据, 0-9为[48-57],A-F为[65-70]

const charCode = splitArr[i].toUpperCase().charCodeAt()

let num

// 字符为[A-F]时, 实际数字为charCode -55

if(charCode >= 65) num = charCode - 55

// 字符为[0-9]时, 实际数字为charCode - 48

else num = charCode - 48

// 当实际数字大于radix时, 无法解析则停止字符串遍历

if (num > radix) {

break

} else {

arr.push(num)

}

}

const len = arr.length

// 当实际数字数组长度为0时, 返回NaN

if(!len) return NaN

let result = 0

// 依次解析实际数字数组, 组合成真正的数字

for(let i = 0; i < len; i++) {

const num = arr[i] * Math.pow(radix, len - i - 1)

result += num

}

// 算法匹配到的正负号

return result * (groups.fuhao === '-' ? -1 : 1)

}

测试用例

const assert = require('assert')

// 以下返回15

assert.strictEqual(_parseInt('0xF', 16), 15)

assert.strictEqual(_parseInt('F', 16), 15)

assert.strictEqual(_parseInt('17', 8), 15)

assert.strictEqual(_parseInt(021, 8), 15)

assert.strictEqual(_parseInt('015', 10), 15)

assert.strictEqual(_parseInt(15.99, 10), 15)

assert.strictEqual(_parseInt('15,123', 10), 15)

assert.strictEqual(_parseInt('FXX123', 16), 15)

assert.strictEqual(_parseInt('1111', 2), 15)

assert.strictEqual(_parseInt('15 * 3', 10), 15)

assert.strictEqual(_parseInt('15e2', 10), 15)

assert.strictEqual(_parseInt('15px', 10), 15)

assert.strictEqual(_parseInt('12', 13), 15)

// 以下返回NaN

assert.strictEqual(_parseInt('Hello', 8), NaN)

assert.strictEqual(_parseInt('546', 2), NaN)

// 以下返回-15

assert.strictEqual(_parseInt('-F', 16), -15)

assert.strictEqual(_parseInt('-0F', 16), -15)

assert.strictEqual(_parseInt('-0XF', 16), -15)

assert.strictEqual(_parseInt(-15.1, 10), -15)

assert.strictEqual(_parseInt(' -17', 8), -15)

assert.strictEqual(_parseInt(' -15', 10), -15)

assert.strictEqual(_parseInt('-1111', 2), -15)

assert.strictEqual(_parseInt('-15e1', 10), -15)

assert.strictEqual(_parseInt('-12', 13), -15)

// 以下返回4

assert.strictEqual(_parseInt(4.7, 10), 4)

assert.strictEqual(_parseInt(4.7 * 1e22, 10), 4)

assert.strictEqual(_parseInt(0.00000000000434, 10), 4)

// 以下返回224

assert.strictEqual(_parseInt('0e0', 16), 224)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值