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

大数相加、相减、相乘的实现 #5

Open
H246802 opened this issue Feb 20, 2019 · 4 comments
Open

大数相加、相减、相乘的实现 #5

H246802 opened this issue Feb 20, 2019 · 4 comments

Comments

@H246802
Copy link
Owner

H246802 commented Feb 20, 2019

在JavaScript 中,我们所可以获取的最大的安全整数区间在于 是 -(2^{53}-1)~ 2^{53}-1 ,即:-9007199254740991 ~ 9007199254740991。也就是说超出这个数以后,精度就得不到保障。但有时候我们的需求不止要这样。我们需要更准确的数字

所以我们可以换一种思路,用字符串来表示数字,比如 "9007199254740991123",这样就不存在四舍五入导致的精度丢失的问题,我们就可以通过对字符串进行 加法 运算得到想要的结果。

@H246802
Copy link
Owner Author

H246802 commented Feb 20, 2019

加法的实现

对于加法,我们可以使用小学的方法,从最后一位开始相加,结果大于 10 就 进位 给前一位数多 一个1。

function add(num1,num2){
  if(typeof(num1) !== 'string' || typeof(num1) !== 'string' ){
    alert('请传入字符串')
    return
  }
  const length = Math.max(num1.length,num2.length)
  // 对数字补位
  num1 = num1.padStart(length,'0')
  num2 = num2.padStart(length,'0')
  let buwei = 0
  let temp = 0
  let result = ''
  for(let i = length -1 ; i >= 0 ;i--){
    temp = buwei + parseInt(num1[i]) + parseInt(num2[i])
    result = (temp % 10) + result
    buwei = parseInt(temp / 10)
  }
  
  result = (buwei === 1 ? '1' : '') + result 
  return result
}
console.log(add('9007199254740991','1229007199254740993443'))

@H246802
Copy link
Owner Author

H246802 commented Feb 20, 2019

减法的实现

对于减法,我们需要进行 减位,同时对于结果,我们需要考虑为负的情况,所以我们需要判断二者大小,取大值减小值的差,视结果判断是否添加负号。

function sub(num1,num2){
  if(typeof(num1) !== 'string' || typeof(num1) !== 'string' ){
    alert('请传入字符串')
    return
  }
  if(num1 === num2){
    return '0'
  }
  const length = Math.max(num1.length,num2.length)
 // 判断两数大小
  let fisrtIsBig = checkBs(num1,num2)
  if(!fisrtIsBig){
    [num1,num2] = [num2,num1]
  }
  
  // 同样进行补位
  num1 = num1.padStart(length,'0')
  num2 = num2.padStart(length,'0')
  
  let jianwei = 0
  let temp = 0
  let result = ''
  
  for(let i = length - 1 ; i >= 0; i--){
   temp = parseInt(num1[i]) -  parseInt(num2[i]) - jianwei
   if(temp < 0){
     jianwei = 1
     result = (10 + temp) + result
   }else{
     result = temp + result 
   }
  }
  result = (fisrtIsBig ? '' : '-1') +  result.replace(/^0+/, '') //去掉前面多余的0,如"1111"-"1110"
  return result
}
// 判断 两个数的大小
function checkBs(num1,num2){
  if(num1.length > num2.length){
   return true
  }else if(num1.length === num2.length){
    return num1 > num2
  }else{
    return false
  }
}
console.log(sub('1315','1314'))

@H246802
Copy link
Owner Author

H246802 commented Feb 20, 2019

乘法的实现

对于乘法,我们可以看做数字每位相乘之后再相加的运算。对于 123412 的相乘 , 可以用以下代码表示

mul('1234','12')   // 等价于
add(mul('1234' , '2') ,(mul('1234', '1') + '0'))

mul('1234','123')   // 等价于
add((mul('1234' , '2') + '0') , (mul('1234', '1') + '00')) , mul('1234' , '3'))

根据以上思路我们可以得到以下代码

function add(num1,num2){
  const length = Math.max(num1.length,num2.length)
  // 对数字补位
  num1 = num1.padStart(length,'0')
  num2 = num2.padStart(length,'0')
  let buwei = 0
  let temp = 0
  let result = ''
  for(let i = length -1 ; i >= 0 ;i--){
    temp = buwei + parseInt(num1[i]) + parseInt(num2[i])
    result = (temp % 10) + result
    buwei = parseInt(temp / 10)
  }
  
  result = (buwei === 1 ? '1' : '') + result 
  return result
}
console.log(add('9007199254740991','1229007199254740993443'))

function mul(num1,num2){
  if(typeof(num1) !== 'string' || typeof(num1) !== 'string' ){
    alert('请传入字符串')
  }
  let buwei = 0
  let temp = 0
  let result = ''
  let tempResult = ''
  for(let i = num2.length-1; i >= 0; i--) {
    tempResult = ''
    buwei = 0
    for(let j = num1.length - 1 ; j >= 0 ; j--){
      temp = buwei + parseInt(num2[i]) * parseInt(num1[j])
      buwei = parseInt(temp / 10)
      tempResult =  (temp % 10) + tempResult
    }
    tempResult = (buwei > 0 ? buwei : '') + tempResult
    result =add(result, tempResult+'0'.repeat(num2.length - 1 -i))
  }
  return result

}
console.log(mul('99999','99'))

@H246802
Copy link
Owner Author

H246802 commented Feb 20, 2019

注:

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

No branches or pull requests

1 participant