b99902HW 板


LINE

话说因为Worksheet有出现简单的大数,所以就PO了篇简单的大数文给大家参考:p。 //是说我绝对不会说内容是偷偷改自之前编的讲义的:P -- 大部分程式语言中的资料型别,其所能储存的值都有一定的范围,那若要做的运算超出 这个范围时该怎麽办?或所需求精准度很高时该怎麽做?等咻碰吗?!当然不可能啦,所以 这时候...嘿嘿~就必须自己写一种资料结构了。 §大数的资料结构实践(Data Structure Implementation) 我们分别使用一个阵列来储存各个位数还有一个变数来纪录大数。 例如:21474836472147483647 以上用大数储存就如下 index : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 value : 7 4 6 3 8 4 7 4 1 2 7 4 6 3 8 4 7 4 1 2 length = 20 话说为什麽是这样反过来存呢?(其实我是正的存!只是index是从左到右写而已XD(无误)) 因为这样两个数字在做运算的时候,第i位才会刚好是对到阵列的第i-1格~ 嗯...我只是觉得这样比较好写啦XD,当然也是有人一直以来都是反过来做= =+。 而且我看大家作业大部分都反过来作,感觉这样还要去对齐位数有点麻烦:p,如果一开始 输入的时候就把字串reverse,可能会比较好做一点这样...。 ※注:因为在 C 的语法中,阵列是由 0 开始存取,所以实际位数是到 length-1。但是以下 伪代码,阵列都是由 1 开始到 length,这点要注意一下。 §大数加法(Addition) 一般来说,我们都是利用直式加减乘除法来做运算,所以说以下的运算方法,皆是使用 直式运算方式来思考。 BIGNUM_ADD (bignum a,bignum b) create c as a bignum c.length ← max( a.length , b.length ) for i ← 1 to c.length do c[i] ← a[i] + b[i] for i ← 1 to c.length do c[i+1] ← c[i+1] + c[i] / 10 c[i] ← c[i] mod 10 if c[c.length] ≠ 0 then c.length ← c.length + 1 return c §大数减法(Subtraction) 基本上有两种想法,一种是最基本的借位补位直式减法,也就是平常最常用的方法。 再来另一种,就是利用补数的概念,来算减法。 也就是先求被除数的补数,再利用加法将两数相加,最後在减掉多出位即可。 例如: 2147483647 – 123456789 = 2147483647 + (10000000000 – 0123456789) –1000000000 = 2147483647 + 9876543211 – 1000000000 = 12024026858 –1000000000 = 2024026858 其中 9876543211 为 0123456789 的 10 补数。而至於实际写法,就请大家自己练习了。 §大数乘法(Multiplication) 与直式乘法相同,将两边的每一位相乘即可。其中要注意的是 a 的第 i 位乘以 b 的第 j 位,会对应到 c 的第 i + j 位,所以我们有以下的写法。 BIGNUM_MULTIPLY (bignum a,bignum b) create c as a bignum c.length ← a.length + b.length for i ← 1 to a.length do for j ← 1 to b.length do c[i + j] ← c[i + j] + a[i] * b[j] for i ← 1 to c.length do c[i+1] ← c[i+1] + c[i] / 10 c[i] ← c[i] mod 10 if c[c.length] ≠ 0 then c.length ← c.length + 1 return c §大数除法(Division) 既然乘法是连加,那除法可以用连减的方式来解决罗?当然是可以的,只是当商数非常 大的时候,你的连减就会变的非常的慢,而且,我刚刚乘法也不是用连加的不是吗 XD。 所以我们还是用老方法,直式除法,就像我们平常熟悉的,一位一位去减下来,所以有以下 的代码。 BIGNUM_DIVIDE (bignum a,bignum b) create c as a bignum b move right for a.length – b.length digits // b * 10^(a .length-b.length) for i ← a.length – b.length downto 0 do if a > b then c[i] ← c[i] + 1 a ← a–b else if a <= b then b move left for 1 digit // b / 10 c.length ← a.length – b.length if c[c.length] = 0 then c.length ← c.length - 1 return c 别看上面写的短短的,自己写过就会知道有多不好写了(笑)。 §大数优化(Bignumber optimization) 事实上,大数运算还可以运用一些技巧来进行优化,想一想?宣告的阵列本身的空间, 只记一位会不会浪费掉?因此很明显的,我们可以利用「压位数」的技巧来使运行速度增快 ,而压位数的意思就是代表阵列里一格不只存一位的意思,但是压位数须要注意的是不要不 小心 Overflow 了,特别是乘法部分。而且压位数的除法会变得复杂一点点,这就留给你们 自己想了。 ※建议:本人不建议直接使用 long long 存取(记忆体使用大并且也比较慢),而较建议用 int 存 7,8 位,只要运算过程记得形态转换就 OK 了。 §小结(Conclusion) 以上介绍的就是基本的大数运算,不过上面只讨论正数问题,当遇到负数怎麽办呢,有 小数点又怎麽办呢?嘿嘿!这时候就必须考验你的智慧了!! 刚开始的时候大数常常会被直接当成一种考题,但是到後来会变成一种出题者心机的手 段,所以当看到一个题目时,先估计数值范围是必要的!但是也不要以为,假如输出答案是 在 int 或 long long 内就不用写大数,在运算过程中 Overflow 或 Downflow 是常有的 事,所以大数的适用与否,必须经过适当的估计,当用则用,以免造成无法挽回的後果!! --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.30.82
1F:推 icehall:推一个 10/27 08:57
※ 编辑: math120908 来自: 140.112.30.82 (10/27 08:58)
2F:推 m80126colin:用心推......话说一个位数存7.8位要怎麽乘呀@@ 10/27 09:06
3F:→ math120908:+-*作法都差不多 改成10^7进位之类的就好了~ 10/27 09:12
4F:→ math120908:除法就要另外想XD 本来除法就是很麻烦的东东:p~~ 10/27 09:12
5F:→ math120908:哦还是你是要问存7,8位会overflow要怎麽乘@_@...? 10/27 09:15
6F:→ math120908:反正就是途中先转成long long之後再转回来吧XDrz 10/27 09:15
7F:推 bztfir:先推再说!!!!! 10/27 09:33
8F:推 OppOops:推!!! 10/27 16:06
9F:推 cluster159:推 10/27 16:11
10F:推 ryan8175ptt:没时间仔细看 先转寄(按)......先推再说! 10/27 16:26
11F:推 jimmy9988:push!!! 10/27 20:00
12F:推 monkey020626:推~ 10/27 20:36
13F:推 yuscvscv:之前好像有看过有文章说转long long效率不会高太多? 10/27 23:47
14F:推 williamiced:推 10/28 00:16
15F:推 MrGreat:推~ 真用心 10/28 07:32
16F:推 alan0511:推 11/08 03:04







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Boy-Girl站内搜寻

TOP