BigInteger in Cpp (造轮子大法第一波) 未完成版本

游荡知乎这么久,甚是仰慕V神。遂开始造轮子之路,由于新手实力较菜。顾从简单的大整数的入门。

功能实现分析:

1. 能用字符串, 长整型(long long or _int64)构造出此BigInteger.

2. 具有正负数之分(整这个整了好一会)

3. 实现基本运算                                    (c,d,e)尚未实现

a 加    b 减

c 乘    d 除

e 取余

4.输入,输出运算符的重载

类整体架构如下。

 1 class BigInt {
 2     friend ostream& operator<<(ostream &os, const BigInt &bi);
 3     friend istream& operator>>(istream &is, BigInt &bi);
 4 public:
 5     BigInt() = default;
 6     BigInt(string in);
 7     BigInt(istream &in);
 8     BigInt(long long in);
 9     void setPositive(bool flag);
10     bool operator<(const BigInt &bi) const;
11     bool operator>(const BigInt &bi) const;
12     bool operator==(const BigInt &bi) const;
13     void valueOf(string in);
14     BigInt operator+(const BigInt &bi);
15     BigInt operator-(const BigInt &bi);16     BigInt operator*(const BigInt &bi);
17 private:
18     //以下为忽略符号的运算 符号问题在重载运算符中判断.
19     BigInt add(const BigInt &bi) const;
20     BigInt minus(const BigInt &bi) const;  //忽视符号的减法 大的数要为this
21     BigInt multiply(short t, int k) const; // t只能是个位数
22     bool less(const BigInt &bi) const;
23     bool equal(const BigInt &bi) const;
24
25     //读取构造
26     void read(string in);
27
28     bool positive = true;
29     vector<short> num;   //存储大数的每一位 逆序 从个位开始
30 };

类API实现如下:

  1 bool BigInt::equal(const BigInt &bi) const {
  2     if (this->num.size() != bi.num.size())
  3         return false;
  4     for (decltype(bi.num.size()) i = 0; i < bi.num.size(); i++) {
  5         if (this->num[i] != bi.num[i])
  6             return false;
  7     }
  8     return true;
  9 }
 10 BigInt BigInt::operator+(const BigInt &bi) {
 11     if (this->positive == bi.positive) {
 12         //存在拷贝构造 性能问题??
 13         BigInt ans = add(bi);
 14         ans.setPositive(bi.positive);
 15         return ans;
 16     }
 17     else {
 18         BigInt ans;
 19         if (this->less(bi)) {
 20             ans = bi.minus(*this);
 21             ans.setPositive(bi.positive);
 22         }
 23         else if (this->equal(bi)) {
 24             ans.num.push_back(0);
 25             return ans;
 26         }
 27         else {
 28             ans = this->minus(bi);
 29             ans.setPositive(this->positive);
 30         }
 31         return ans;
 32     }
 33
 34 }
 35 BigInt BigInt::operator-(const BigInt &bi) {
 36     if (this->positive == bi.positive) {
 37         BigInt ans;
 38         if (this->less(bi)) {
 39             ans = bi.minus(*this);
 40             ans.setPositive(!this->positive);
 41         }
 42         else if (this->equal(bi)) {
 43             ans.num.push_back(0);
 44         }
 45         else {
 46             ans = this->minus(bi);
 47             ans.setPositive(this->positive);
 48         }
 49         return ans;
 50     }
 51     else {
 52         BigInt ans = this->add(bi);
 53         ans.setPositive(this->positive);
 54         return ans;
 55     }
 56 }
 57 BigInt BigInt::operator*(const BigInt &bi) {
 58     if (*this == *(new BigInt(0)) || bi == *(new BigInt(0))) {
 59         BigInt ans;
 60         ans.num.push_back(0);
 61         return ans;
 62     }
 63     else {
 64         int t = 0;
 65         // 使用隐式转换 安全?
 66         BigInt ans = 0;
 67         for (decltype(num.size()) i = 0; i < num.size(); i++) {
 68             ans = ans + bi.multiply(i, t);
 69             t++;
 70         }
 71         if (this->positive != bi.positive) {
 72             ans.setPositive(false);
 73         }
 74         return ans;
 75     }
 76 }
 77 void BigInt::setPositive(bool flag) {
 78     this->positive = flag;
 79 }
 80 bool BigInt::operator==(const BigInt &bi) const {
 81     if (this->positive != bi.positive)
 82         return false;
 83     else {
 84         if (this->num.size() != bi.num.size())
 85             return false;
 86         for (decltype(bi.num.size()) i = 0; i < bi.num.size(); i++) {
 87             if (this->num[i] != bi.num[i])
 88                 return false;
 89         }
 90         return true;
 91     }
 92 }
 93 bool BigInt::operator<(const BigInt &bi) const {
 94     if (this->positive == true) {
 95         if (bi.positive == false)    //this为正 bi为负
 96             return false;
 97         else {    //this与bi同为正
 98             if (this->num.size() > bi.num.size())   //长度长的大
 99                 return false;
100             else if (this->num.size() < bi.num.size())
101                 return true;
102             bool flag = false;
103             //一样长的时候比较为一位 注意要逆序比较 以为数字的首位存在容器的最后一位
104             for (int i = this->num.size() - 1; i >= 0; i--) {
105                     if (this->num[i] > bi.num[i]) {
106                         flag = true;
107                         break;
108                     }
109             }
110             return flag;
111
112         }
113     }
114     else {   // 跟以上反过来就行了
115         if (bi.positive == true)  //this为负 bi为正
116             return true;
117         else { //同为负数时
118             if (this->num.size() > bi.num.size())
119                 return true;
120             else if (this->num.size() < bi.num.size())
121                 return false;;
122             bool flag = false;
123             for (int i = this->num.size() - 1; i >= 0; i--) {
124                     if (this->num[i] < bi.num[i]) {
125                         flag = true;
126                         break;
127                     }
128             }
129             return !flag;
130         }
131     }
132
133 }
134 bool BigInt::operator>(const BigInt &bi) const {
135     if (*this < bi)
136         return false;
137     else if (*this == bi)
138         return false;
139     else
140         return true;
141 }
142 istream& operator>>(istream &in, BigInt &bi) {
143     string input;            //读取所创建的大数
144     in >> input;
145     while (!bi.num.empty())
146         bi.num.clear();
147     try {
148         if (input[0] == ‘-‘)
149             bi.positive = false;
150         else
151             bi.positive = true;
152         for (int i = input.size() - 1; i >= 0; i--) {
153             if (0 == i && !bi.positive)
154                 break;
155             if (input[i] < ‘0‘ || input[i] > ‘9‘)
156                 throw runtime_error("You should input a positive integer.");
157             bi.num.push_back(input[i] - ‘0‘);
158         }
159     }
160     catch (runtime_error e) {
161         std::cerr << e.what() << endl;
162     }
163     return in;
164 }
165 ostream& operator<<(ostream &os, const BigInt &bi) {
166     // 逆序输出
167     if (!bi.positive)
168         os << "-";
169     for (int i = bi.num.size() - 1; i >= 0; i--) {
170         os << bi.num[i];
171     }
172     return os;
173 }

今天先撸到这里。 让我再想想乘除的实现方法吧

                            Vane_Tse On the Road. 2014-06-18 21:42:56

BigInteger in Cpp (造轮子大法第一波) 未完成版本

时间: 2024-10-07 12:04:08

BigInteger in Cpp (造轮子大法第一波) 未完成版本的相关文章

造轮子:新建一个属于自己的String类

练习造轮子,新建一个属于自己的MyString类 首先来开启检测内存泄漏的函数 在main里添加 _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF); 开启内存泄漏检测 int main() { _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF); int *p = new int; return

python 造轮子(一)——序列与字典

虽然说造轮子很少用了,什么底层东西很少写,但是还是很想学扎实,还是好多东西还是的会,没有底层的支持,比较高级的库学起来还是很困难的. 序列的普遍用法: 1 #-*-coding:utf8-*- 2 3 #索引 4 l = [1,2,3,4] 5 t = (1,2,3,4) 6 d = {1:1,2:2,3:3,4:4} 7 8 9 print l[0] 10 print t[0] 11 print d[1] #键索引 12 13 #切片 14 15 print l[0:5] 16 print t

GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。

1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便地使用所有版本的Android动作栏的设计模式. 对于Android 4.0及更高版本,ActionBarSherlock可以自动使用本地ActionBar实现,而对于之前没有ActionBar功能的版本,基于Ice Cream Sandwich的自定义动作栏实现将自动围绕布局.能够让开发者轻松开发

我们为什么喜欢重新造轮子

不要重新造轮子,是英文don't re invite wheel的直译.什么是轮子呢,我们一般认为一个通用中间件或框架,和实际业务没有直接关系的代码,就是轮子.这些代码虽然不是实质的业务逻辑,但是在一个项目中往往是担当骨架的作用. 程序员新手的眼中,这些代码就是经验的象征.在很多项目组中,只有经验丰富的老程序员才有机会去设计和选择这些轮子.可以设计可重用的干货代码,也就成为很多对技术有追求的程序员的努力方向.有几年工作经验,在技术上寻求发展的程序员大多都会自己设计和实现一些经典的轮子,这也成为了

Hybrid App Development: 二、关于造轮子以及在Xcode iOS应用开发中加入Cordova

转载请注明出处:http://www.cnblogs.com/xdxer/p/4111552.html [ctrl+左键点击图片可以查看原图] 在上一篇关于Hybrid App Development的文章中,我讨论了一下在iOS下UIWebView的使用方法.但是光使用一个UIWebView所提供的功能还是完全不能满足我们的需求.   关于造轮子的思考: 在UIKit中的UIWebView虽然已经提供了很多功能了,比如JavaScript和Objc之间的通信.但是考虑到一个问题,如果在Hybr

避免重复造轮子的UI自动化测试框架开发

一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览器的基本上底层都是selenium,驱动无线app和浏览器基本是appium.monkey之类的,底层都是基于官方支持的自动化测试框架开发而来,然后上层又做了各种封装 首先在开始计划开发自动化时,第一步是了解目前已有的自动化开发技术,上面说了,最底层的就那几种,根据实际要去测试的业务需求选择合适的自

第27篇 重复造轮子---模拟IIS服务器

在写程序的时候,重复造轮子是程序员的一个大忌,很多人对重复造轮子持有反对的态度,但是我觉得这个造轮子的过程,是对于现有的知识的一个深入的探索的过程,虽然我们不可能把轮子造的那么的完善,对于现在有的东西是一个更好的理解和使用.   当你打开一个网页时,你会看到一个html页面的呈现,当然这是一个完整的Http的请求和响应的过程,无非是对HTML+CSS+JS一个综合的产物,在这个过程中浏览器请求数据的过程中会发出一个有一个格式的字符串(基于http协议生成的http请求报文),服务器在接收这样的一

Js造轮子,基础篇

在js中,只要不是在函数内部声明的函数都是全局变量了,如果代码量大的情况全局变量的污染是非常可怕的,所以需要造轮子声明自己的变量和自己的全局变量和函数方法 一,声明一个对象 先简单的声明一个对象tool={},这样就可以了,这样一个简单的全局对象就弄好了 二,声明方法和变量 这时候定义方法和变量就可以这样了 1 window.tool = {} 2 window.tool.cip = localStorage.cip; 3 4 //url 5 tool.urlHeader = 'http://1

何为造轮子?

著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:王子亭链接:http://www.zhihu.com/question/21818673/answer/20473677来源:知乎 显然,车轮子是圆形的,这是大家公认的,最合适的形状.而你非要发明另一种形状的轮子,这种行为就叫「重复发明轮子(Reinventing the wheel)」,即「造轮子」.「造轮子」的含义:明知道你做的不可能比前辈做得更好,却仍然坚持要做. 放到编程中,就是说业界已经有公认的软件或者库了,你明