大整数的四则运算已经是老生常谈的问题了。很多的库也已经包含了各种各样的解决方案。

作为练习,我们从最简单的加减法开始。

加减法的核心思路是用倒序数组来模拟一个大数,然后将两个大数的利用竖式进行运算。

加法函数:

  • 异符号相加时调用减法函数(减法函数后面给出)
  • 同符号相加先确定符号
  • 因为输入输出的为字符串,需要去除字符串开头的0
  1. function add(a, b) { /*输入两个字符串类型大数字*/
  2.  
  3. if(a.indexOf('-') >= 0 && b.indexOf('-') < 0){
  4.  
  5. return minus(b,a);
  6. }
  7. else if(a.indexOf('-') < 0 && b.indexOf('-') >= 0){
  8.  
  9. return minus(a,b);
  10. }
  11.  
  12. var sign = "";
  13.  
  14. if(a.indexOf('-') >= 0 && b.indexOf('-') >= 0){ /*两个负数相加,指定符号*/
  15.  
  16. sign = "-";
  17.  
  18. a = a.substr(1);
  19.  
  20. b = b.substr(1);
  21. }
  22.  
  23. var aArr = a.replace(/^0+/,'').split('').reverse();
  24.  
  25. var bArr = b.replace(/^0+/,'').split('').reverse(); /*利用倒序数组存储*/
  26.  
  27. var carry = 0; /*进位值*/
  28.  
  29. var sumArr = [];
  30.  
  31. var len = Math.max(aArr.length, bArr.length); /*取得位数较大的一个数的位数*/
  32.  
  33. for(var i=0;i<=len-1;i++){
  34.  
  35. var digA = parseInt(aArr[i]) ? parseInt(aArr[i]) : 0;
  36.  
  37. var digB = parseInt(bArr[i]) ? parseInt(bArr[i]) : 0;
  38.  
  39. var digTotal = digA + digB + carry;
  40.  
  41. if(i == len-1){/*排除'012' + '012'这样的情况*/
  42.  
  43. if(digTotal > 0){
  44.  
  45. sumArr.unshift(digTotal);
  46. }
  47.  
  48. break;
  49. }
  50.  
  51. carry = Number(digTotal >= 10);
  52.  
  53. digTotal = digTotal % 10;
  54.  
  55. sumArr.unshift(digTotal);
  56.  
  57. }
  58.  
  59. return sign + sumArr.join('');
  60. }

在写减法时,发现需要先比较大小,因此需要一个大数字比较大小的函数

比较小大函数:

  • 异符号比较大小,正数大于负数
  • 正数比较大小,先比较长度,长度大的数值大
  • 正数长度一致,从最高位开始逐位比较,只到出现较大的一方,则数值更大
  • 负数比较大小,方法同正数,结果取反即可
  • 因为输入输出的为字符串,需要去除字符串开头的0
  1. function compare(a,b){
  2.  
  3. var sign = 1;
  4.  
  5. if(a.indexOf('-') >= 0 && b.indexOf('-') < 0){ /*异符号比较*/
  6.  
  7. return -1;
  8. }
  9. else if(a.indexOf('-') < 0 && b.indexOf('-') >= 0){ /*异符号比较*/
  10.  
  11. return 1;
  12. }
  13. else if(a.indexOf('-') >= 0 && b.indexOf('-') >= 0){ /*同为负数,指定取反,同时改为正数比较方式*/
  14.  
  15. sign = -1;
  16.  
  17. a = a.substr(1);
  18.  
  19. b = b.substr(1);
  20. }
  21.  
  22. a = a.replace(/^0+/,'');
  23.  
  24. b = b.replace(/^0+/,'');
  25.  
  26. var flag;
  27.  
  28. if(a.length < b.length){ /*比较长度*/
  29.  
  30. flag = -1;
  31. }
  32. else if(a.length > b.length){
  33.  
  34. flag = 1;
  35. }
  36. else{
  37.  
  38. flag = 0;
  39. }
  40.  
  41. if(flag == 0){ /*相同长度逐位比较*/
  42.  
  43. var aArr = a.split('');
  44.  
  45. var bArr = b.split('');
  46.  
  47. for(var i=0;i<=aArr.length;i++){
  48.  
  49. if(aArr[i] > bArr[i]){
  50.  
  51. flag = 1;
  52.  
  53. break;
  54. }
  55. else if(aArr[i] > bArr[i]){
  56.  
  57. flag = -1;
  58.  
  59. break;
  60. }
  61. }
  62. }
  63.  
  64. return sign * flag;
  65. }

减法函数:

  • 异符号相减时调用加法函数
  • 同符号相减需要先确定大小
  • 因为输入输出的为字符串,需要去除字符串开头的0
  1. function minus(a, b) {
  2.  
  3. if(a.indexOf('-') >= 0 && b.indexOf('-') < 0){
  4.  
  5. return add(a,"-" + b);
  6. }
  7. else if(a.indexOf('-') < 0 && b.indexOf('-') >= 0){
  8.  
  9. a = a.substr(1);
  10.  
  11. return add(a,b);
  12. }
  13.  
  14. var sign = "";
  15.  
  16. if(compare(a,b) < 0){
  17.  
  18. var temp = b;
  19.  
  20. b = a;
  21.  
  22. a = temp;
  23.  
  24. sign = "-";
  25. }
  26.  
  27. var aArr = a.replace(/^0+/,'').split('').reverse();
  28.  
  29. var bArr = b.replace(/^0+/,'').split('').reverse(); /*利用倒序数组存储*/
  30.  
  31. var borrow = 0; /*借位值*/
  32.  
  33. var minusArr = [];
  34.  
  35. var len = Math.max(aArr.length, bArr.length); /*取得位数较大的一个数的位数*/
  36.  
  37. for(var i=0;i<=len-1;i++){
  38.  
  39. var digA = parseInt(aArr[i]) ? parseInt(aArr[i]) : 0;
  40.  
  41. var digB = parseInt(bArr[i]) ? parseInt(bArr[i]) : 0;
  42.  
  43. var digMinus;
  44.  
  45. if(i == len-1){
  46.  
  47. if(digA - borrow <= digB){ /*最高位不够减直接跳出循环*/
  48.  
  49. break;
  50. }
  51. }
  52.  
  53. if(digA - digB - borrow >= 0){
  54.  
  55. digMinus = digA - digB - borrow;
  56.  
  57. }else{
  58.  
  59. digMinus = digA + 10 - digB - borrow;
  60.  
  61. borrow = 1;
  62. }
  63.  
  64. minusArr.unshift(digMinus);
  65.  
  66. }
  67.  
  68. return sign + minusArr.join('');
  69. }

以上给出的是带符号大整数加减法基础实现,但效率并不是特别高。

网上也有通过10000进制优化的竖式算法,以及通过位运算实现四则运算的方法,大家也可以搜索看看,今天的练习就到这里了,下周会给出乘除法的基本实现。


如果喜欢我的文章,可以扫描二维码关注我的微信公众号

争取每天都分享一点我自己的开发和练习体验~

Code Kata:大整数比较大小&大整数四则运算---加减法 javascript实现的更多相关文章

  1. 编写Java程序,实现从控制台输入对应个数的整数,输出对输入整数的从大到小显示

    编写Java程序,实现从控制台输入对应个数的整数,输出对输入整数的从大到小显示 效果如下: 实现代码: import java.util.Arrays; import java.util.Scanne ...

  2. Go语言的9大优势和3大缺点, GO语言最初的定位就是互联网时代的C语言, 我为什么放弃Go语言

    Go语言的9大优势和3大缺点 转用一门新语言通常是一项大决策,尤其是当你的团队成员中只有一个使用过它时.今年 Stream 团队的主要编程语言从 Python 转向了 Go.本文解释了其背后的九大原因 ...

  3. Linux 查看磁盘容量、查找大文件、查找大目录

    Linux 查看磁盘容量.查找大文件.查找大目录 磁盘统计 查看磁盘使用情况 df -h 文件统计 查找/home 目录下大于800M的文件 find /home -type f -size +800 ...

  4. bat坐拥大数据。数据挖掘/大数据给他们带来什么。

    阿里巴巴CTO即阿里云负责人王坚博士说过一句话:云计算和大数据,你们都理解错了.   实际上,对于大数据究竟是什么业界并无共识.大数据并不是什么新鲜事物.信息革命带来的除了信息的更高效地生产.流通和消 ...

  5. 如何用一个语句判断一个整数是不是二的整数次幂——从一道简单的面试题浅谈C语言的类型提升(type promotion)

    最近招聘季,看JULY大哥的面试100题时,碰到这么一个扩展问题: 如何用一个语句判断一个整数是不是二的整数次幂?(此题在编程之美也有) easy, 2的整数次幂的二进制形式只有一个1,只要用i和i- ...

  6. 跟上节奏 大数据时代十大必备IT技能

    跟上节奏 大数据时代十大必备IT技能 新的想法诞生新的技术,从而造出许多新词,云计算.大数据.BYOD.社交媒体……在互联网时代,各种新词层出不穷,让人应接不暇.这些新的技术,这些新兴应用和对应的IT ...

  7. SWAP_JOIN_INPUTS Oracle Hint(处理hash join强制大表(segment_size大)作为被驱动表)

    SWAP_JOIN_INPUTS Oracle Hint(处理hash join强制大表(segment_size大)作为被驱动表) swap_join_inputs是针对哈希连接的hint,它的含义 ...

  8. 随机产生1-12的整数 , 根据产生整数输出一下该月份的季节信息(Math.random()和if语句的应用)

    package com.summer.cn; /** * @author Summer *随机产生1-12的整数 , 根据产生整数输出一下该月份的季节信息 */ public class Test04 ...

  9. 给出一个整数,将这个整数中每位上的数字进行反转(JavaScript编程)

    一.问题描述:给出一个整数,将这个整数中每位上的数字进行反转.示例:输入:123,输出321:输入-123,输出-321:输入120,输出-21 二.问题分析与解决: 需要将给出的整数反转,注意示例中 ...

随机推荐

  1. 更新Android Studio 3.0碰到的问题

    更新完后试下运行正在维护的旧项目,出现各种错误,因为后来发现问题不在这,所以没记完整,大概如下: A larger heap for the Gradle daemon is recommended ...

  2. LeetCode 204. Count Primes (质数的个数)

    Description: Count the number of prime numbers less than a non-negative number, n. 题目标签:Hash Table 题 ...

  3. Spring + Fastweixin 微信开发

    这篇文章转自<http://www.qtdebug.com/spring-weixin/> 微信有两种模式,编辑模式和开发者模式,有些功能是互斥的,不可以同时使用,微信开发需要在开发者模式 ...

  4. 本地存储之localStorage

    localStorage 本地存储 .对象.存数据 .取数据 存储的数据量在20M左右 localStorage 是window下面的属性,用的时候可以省略window 数据只能存储字符串类型的 lo ...

  5. TiDB 作为 MySQL Slave 实现实时数据同步

    由于 TiDB 本身兼容绝大多数的 MySQL 语法,所以对于绝大多数业务来说,最安全的切换数据库方式就是将 TiDB 作为现有数据库的从库接在主 MySQL 库的后方,这样对业务方实现完全没有侵入性 ...

  6. kettle介绍

    Kettle也叫PDI,在2006年Kettle加入了开源的BI组织Pentaho,正式命名为PDI,英文全称为Pentaho Data Integeration.Kettle是"Kettl ...

  7. input光标高度问题

    input输入框光标高度问题IE:不管该行有没有文字,光标高度与font-size大小一致 FF:该行没有文字时,光标大小与input的 height 大小一致:该行有文字时,光标大小与font-si ...

  8. android版火狐调试器

    Remotely debugging Firefox for Android 使用火狐开发工具可以在桌面上进行远程代码的调试(FF26以上) 具体使用参考: https://developer.moz ...

  9. filereader api 类型

    filereader类似XMLHttpRequest,只是它用来从文件系统读取文件,提供了不同的方法去读取文件数据:1.readAsText2.readAsDataURL3.readAsBinaryS ...

  10. RPC 调用简述

    首先了解什么叫RPC,为什么要RPC,RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网 ...