实现toString
先实现整数的2进制toString方法
Number.prototype._toString = function() {
let str = '', flag = this < 0 ? '-' : '';
let num = Math.abs(this);
do{
str = num % 2 + str;
num = Math.floor(num / 2);
} while (num);
return flag + str;
}
然后实现小数的2进制toString方法
Number.prototype._toString = function() {
let str = '', flag = this < 0 ? '-' : '';
let integer = Math.floor(Math.abs(this));
let decimal = Math.abs(this) - integer;
do{
str = integer % 2 + str;
integer = Math.floor(integer / 2);
} while (integer);
if (decimal) {
str += '.';
do {
const t = decimal * 2;
str += (t < 1 ? '0' : '1');
decimal = t < 1 ? t : t - 1;
} while (decimal && str.length < 54);
}
return flag + str;
}
接着添加参数,实现toString(radix)方法
Number.prototype._toString = function(radix = 10) {
if (radix < 2 || radix > 36) throw new RangeError("toString() radix argument must be between 2 and 36");
let str = '', flag = this < 0 ? '-' : '';
let integer = Math.floor(Math.abs(this));
let decimal = Math.abs(this) - integer;
const numArr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
do{
str = numArr[integer % radix] + str;
integer = Math.floor(integer / radix);
} while (integer);
if (decimal) {
str += '.';
do {
const t = decimal * radix;
const i = Math.floor(t);
str += numArr[i];
decimal = t - i;
} while (decimal && str.length < 54);
}
return flag + str;
}
最后处理小数精度问题,上述方法精度远超原生精度,需要进行删减。javascript表示数字有1位符号位,11位指数部分,52位小数部分。
Number.prototype._toString = function(radix = 10) {
if (radix < 2 || radix > 36) throw new RangeError("toString() radix argument must be between 2 and 36");
let str = '', flag = this < 0 ? '-' : '';
let integer = Math.floor(Math.abs(this));
let decimal = Math.abs(this) - integer;
const numArr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
do{
str = numArr[integer % radix] + str;
integer = Math.floor(integer / radix);
} while (integer);
if (decimal) {
str += '.';
const maxLen = getMaxLen(radix) + 1;
do {
const t = decimal * radix;
const i = Math.floor(t);
str += numArr[i];
decimal = t - i;
} while (decimal && str.length < maxLen);
}
function getMaxLen(radix) {
let num = Math.pow(2, 53);
let maxLen = 0;
while(num > 1) {
num = Math.floor(num / radix);
maxLen++;
}
return maxLen;
}
return flag + str;
}
实现parseInt
先实现10进制的parseInt方法
window._parseInt = function (str) {
str = String(str).trim();
let index = ['-', '+'].indexOf(str.charAt(0));
if (index > -1) {
str = str.substring(1, str.length);
}
let i = 0, res = '';
while(str.charAt(i) <= '9' && str.charAt(i) >= '0') {
res += str.charAt(i++);
}
return res == '' ? NaN : +res * Math.pow(-1, index + 1);
}
最后实现parseInt(str, radix)方法
window._parseInt = function (str, radix) {
if (radix < 2 || radix > 36) return NaN;
str = String(str).trim();
const index = ['-', '+'].indexOf(str.charAt(0));
if (index > -1) {
str = str.substring(1, str.length);
}
if (!radix) {
if (str.startsWith('0x') || str.startsWith('0X')) {
str = str.substring(2, str.length);
radix = 16;
} else {
radix = 10;
}
}
let i = 0, res = 0;
const numArr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'].slice(0, radix);
while(numArr.includes(str.charAt(i).toLowerCase())) {
res *= radix;
res += numArr.indexOf(str.charAt(i++).toLowerCase());
}
return i == 0 ? NaN : res * Math.pow(-1, index + 1);
}
实现parseFloat
window._parseFloat = function(str) {
let num = _parseInt(str, 10);
if (isNaN(num)) return num;
str = String(str).split('.')[1];
if (!str) return num;
const isMinus = num < 0 ? -1 : 1;
let i = 0;
const numArr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
while(numArr.includes(str.charAt(i))) {
num += numArr.indexOf(str.charAt(i++)) / Math.pow(10, i) * isMinus;
}
return num;
}