Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

面试题库#1——实现(5).add(2).mintes(3)=4 #1

Open
yangxy6 opened this issue Jul 9, 2019 · 0 comments
Open

面试题库#1——实现(5).add(2).mintes(3)=4 #1

yangxy6 opened this issue Jul 9, 2019 · 0 comments

Comments

@yangxy6
Copy link
Owner

yangxy6 commented Jul 9, 2019

首先看到题干第一反应和楼上几位一样,链式操作+给Number/Object对象添加方法。

Number.prototype.add = function(i=0){
	return this.valueOf()+i
}
Number.prototype.minus = function(i=0){
	return this.valueOf()-i
}

不知道是否是考虑的不周全,就仔细想想,感觉会有一些好玩的知识点在里面,就做了一些小实验。
在 Chrome 的 DevTools 里,我们可以做这个实验:
image
这里问题就来了——JS的经典的浮点数陷阱。
在简单地搜索之后,我在 GitHub 上搜到了一位阿里大佬的解法,然后参考了一下他的解法和楼上大佬们的解法,对我上面的答案进行了如下修正:

Number.MAX_SAFE_DIGITS = Number.MAX_SAFE_INTEGER.toString().length-2
Number.prototype.digits = function(){
	let result = (this.valueOf().toString().split('.')[1] || '').length
	return result > Number.MAX_SAFE_DIGITS ? Number.MAX_SAFE_DIGITS : result
}
Number.prototype.add = function(i=0){
	if (typeof i !== 'number') {
        	throw new Error('请输入正确的数字');
    	}
	const v = this.valueOf();
	const thisDigits = this.digits();
	const iDigits = i.digits();
	const baseNum = Math.pow(10, Math.max(thisDigits, iDigits));
	const result = (v * baseNum + i * baseNum) / baseNum;
	if(result>0){ return result > Number.MAX_SAFE_INTEGER ? Number.MAX_SAFE_INTEGER : result }
	else{ return result < Number.MIN_SAFE_INTEGER ? Number.MIN_SAFE_INTEGER : result }
}
Number.prototype.minus = function(i=0){
	if (typeof i !== 'number') {
        	throw new Error('请输入正确的数字');
    	}
	const v = this.valueOf();
	const thisDigits = this.digits();
	const iDigits = i.digits();
	const baseNum = Math.pow(10, Math.max(thisDigits, iDigits));
	const result = (v * baseNum - i * baseNum) / baseNum;
	if(result>0){ return result > Number.MAX_SAFE_INTEGER ? Number.MAX_SAFE_INTEGER : result }
	else{ return result < Number.MIN_SAFE_INTEGER ? Number.MIN_SAFE_INTEGER : result }
}

【大数加减:直接通过 Number 原生的安全极值来进行判断,超出则直接取安全极值】
【超级多位数的小数加减:取JS安全极值位数-2作为最高兼容小数位数】
image

这样就能相对比较完善地解决这个问题了~希望大家多多补充

Originally posted by @noctiomg in Advanced-Frontend/Daily-Interview-Question#88 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant