C++高精度实数类实现[0]
来源:互联网 发布:远行星号舰船数据 编辑:程序博客网 时间:2024/05/16 06:35
自学C++也有近一个月了,中途研究了一段时间MFC,感觉挺难得。想了想还是先把基础学好,不要好高骛远吧~
于是乎俺决定自己写一个C++的高精度实数类,乍一想貌似比较容易咔咔
以前在Java里用过 BigInteger 和 BigDecimal 这样的基于字符串实现的大整数、高精度小数的类。我希望自己能编写一个类似实现的C++类。
由于整数也是小数的一种,我就偷个懒,直接写高精度实数类好啦
类名就叫 d_BigDecimal 了,看似有点不伦不类哈~这个d就是俺名字的首字母咯
我设想的这个类对外提供一个构造函数,接收一个C风格字符串(const char*)来构造指定实数。之所以不使用C++提供的string类,算是个人的小脾气吧(不用你们的类库俺也能做得好~)
下面是很重要的一步了,内部数据如何存储?这直接关系到运行时的效率。由于该类是很基础的一个类,我想尽可能的让运算效率提高~此处得动动脑子了
可惜的是,我一没学过数据结构,二没学过算法分析,只能凭空乱想啦~~~
以下内容纯属个人浅见,不对勿喷哦
很显然,如果在内部存储时不做任何处理,直接利用构造函数中传递进来的字符数组,然后以10进制的加减乘除做运算,效率是极其低下的,其中涉及到进位尤其麻烦。我第一个排除了这种想法。
用2进制存储或许是个好主意。首先,2进制数的加法虽然也有进位,但是情况简单,便于处理,这对降低编写代码的复杂度有所帮助。当然,更重要的一个理由是,我认为2进制的乘除运算比10进制在运行效率上要高得多。
举一个例子:
10进制中
19.625 和 23.375
这两个数的2进制形式分别是
10011.101 和 10111.011
做乘法运算,当然先忽略小数点
19625 * 23375
-> 19625 * 5 -> 5 * 5 -> 25 * 1 -> 25
-> 2 * 5 -> 10 * 10 -> 100
-> 6 * 5 -> 30 * 100 -> 3000
-> 9 * 5 -> 45 * 1000 -> 45000
-> 1 * 5 -> 5 * 10000 -> 50000
-> 25 + 100 + 3000 + 45000 + 50000 -> 98125
-> 98125 * 1 -> 98125
-> 19625 * 7 ->……
->……
->……
->……
->……
->……
->……
-> 137375 * 10 -> 1373750
-> 19625 * 3 ->……
-> 19625 * 3 ->……
-> 19625 * 2 ->……
-> 458734375
大约进行了100次加法运算才得到结果(忽略小数点),这其中还默许了10以内的数相乘结果直接由程序提前穷举给出,否则计算量更大
在看看2进制下的运算呢?
10011101 * 10111011
-> 10011101 * 1 ->10011101 * 1 -> 10011101
-> 10011101 * 1 -> 10011101 * 10 -> 100111010
-> 10011101 * 0 -> 0
-> 10011101 * 1 -> 10011101 * 1000-> 10011101000-> 10011101 * 1 -> 10011101 * 10000-> 100111010000
-> 10011101 * 1 -> 10011101 * 100000-> 1001110100000
-> 10011101 * 0 -> 0
-> 10011101 * 1 -> 10011101 * 10000000-> 100111010000000
-> 10011101 + 100111010 + 10011101000 + 100111010000 + 1001110100000 + 100111010000000
-> 111001010101111
仅仅23次运算就得出了结果(忽略小数点),并且不需要像10进制乘法一样给出乘法表。其中优劣显而易见。
决定用2进制形式存储数据了,自然而然就会想到用一个存放了一串0、1的数组来实现咯~嗯,还需要一个变量表示小数点所在位数
比如用户输入"19.625"(2进制10011.101),我们在内部就有一个这样的数组对应 {1, 0, 1, 1, 1, 0, 0, 1, 0}
注意,这里是从低位开始往高位排序的,最高位表示符号位,0是整数1是负数(好吧,我承认抄袭了原码补码的那一套),然后小数点所在位数是3。这样,一个高精度的实数就被我们表示出来啦~
写到这里,突然发现一个小问题呀,哎,不写BigInteger直接写BigDecimal果然有一点不好……这个表示小数点所在位数的变量似乎限制了我们的精度,就算用unsinged long来存储这个变量,也只能表示小数点后2^32-1位小数额。如果提前写好了BigInteger,那就没有限制啦~
不过这么一点点小问题也无所谓了~写完以后再修改也很容易。况且……2^32-1位小数也够用啦!
那么,这个存储2进制数的数组用什么类型呢?int给人的感觉太大了,毕竟只需要0和1两个变量就可以了。short呢?或许是个好主意,难道没有更短的了吗?
当然有,bool就是~
一个bool型数据在内存中占1字节,short占2字节,int是4字节。我们的高精度数需要大量存储这样的数据,当然是越小越好咯。当然,char也是一个不错的选择,它在内存中也仅占1字节。但从另一个角度考虑,bool只有两种状态,在我们采用2进制存储的前提下,更为方便!
于是,我们终于确定了d_BigDecimal的两个成员变量:
bool decimal_bin[];unsigned long point_index;
接下来的问题就是,如何在构造函数中将用户传入的以10进制表示的字符串数字转化为我们内存中的数据了。
写了这么久,也有点累了,剩下的下次再讨论吧~~~
- C++高精度实数类实现[0]
- HDU-1753 实数高精度加法
- HDU-1063 高精度实数乘法
- uva784 Exponentiation (实数高精度乘方)
- 高精度任意长度实数乘法
- Hdu 1063 & Poj 1001 Exponentiation (java 高精度实数 去除首尾0)
- 高精度运算——实数乘法
- uva 748 Exponentiation(高精度实数乘法)
- C语言实现的高精度计算器
- 求解高精度幂c语言实现
- 关于C语言实现高精度乘法运算
- C语言实现的高精度加法
- 高精度加法的c语言实现
- 【高精度】高精度分数[c++]
- C++bign类高精度模板
- C/C++高精度计时器类
- 高精度模板 c++/类封装
- 实现复数与实数类中的运算符重载
- 查找字符串
- 工具综合症?资料收集狂?
- 5中方法避免压力过大
- c#画图实现立方体(压缩文件体积图)
- GDI vs GDI+
- C++高精度实数类实现[0]
- The world’s next OS is here. Get the first-mover advantage.
- Sublime Text 2 - 性感无比的代码编辑器!程序员必备神器!
- 管理Oracle ASM实例
- 新博客
- 填入空隙(setbkcolor,setbkmode)
- 扯淡-Linux 内核中的 GCC 特性在程序中的应用
- sql_修改表结构
- CSS3中轻松实现渐变效果