实现思路
- 将减数和被减数扩大n倍,然后相减,最后结果再缩小n倍。
- 使用字符串,补全减数和被减数小数点后面的小数(根据最长的一个值补全)。
- 去掉小数点,转为整数;计算;在之前小数位置添加上小数点。
- 处理一下正负数 。
- js, number 类型使用 IEEE 754 格式表示整数和浮点值。注意这里放大后的数要在 2^53 内。
代码实现(方法一)
function fn(a, b) {
// 是否正数
let positiveNumber = true
if(a<b){
[a,b] = [b,a]
positiveNumber = false
}
let aStr = a.toString()
let bStr = b.toString()
let aArr = aStr.split('.')
let bArr = bStr.split('.')
let aLen = aArr[1]?aArr[1].length : 0
let bLen = bArr[1]?bArr[1].length : 0
// 获取最后的小数位数
let maxLen = Math.max(aLen, bLen)
aStr = parseFloat(aStr).toFixed(maxLen)
bStr = parseFloat(bStr).toFixed(maxLen)
aStr = aStr.split('.').join('')
bStr = bStr.split('.').join('')
let result = parseFloat(aStr) - parseFloat(bStr)
// 从尾巴往前 maxLen 位置就是小数点插入位置
result = result.toString().split('').reverse().join('')
// 少于小数点长度需要补全
result = result.padEnd(maxLen + 1, '0')
result = result.split('')
result.splice(maxLen, 0, '.')
result = result.reverse().join('')
if(!positiveNumber){
result = '-' + result
}
return result
}
代码实现(方法二)思路和一同,简化版
function fn(a, b) {
let aDecimalLen, // a 小数长度
bDecimalLen, // b 小数长度
maxLen, // 最长的小数长度
multiple
try{
aDecimalLen = a.toString().split('.').length
}catch (e) {
aDecimalLen = 0
}
try{
bDecimalLen = b.toString().split('.').length
}catch (e) {
bDecimalLen = 0
}
maxLen = Math.max(aDecimalLen, bDecimalLen)
multiple = Math.pow(10, maxLen)
return ((a * multiple - b * multiple) / multiple).toFixed(maxLen)
}
验证
let a = 0.02
let b = 0.01
console.log(fn(a, b))
console.log(a - b)