在计算机语言中的乘法,LOGO语言编程题  高精度乘法★★

不限制位数的整数高精度乘法★★★★

这是“高精度算法”系列文章中的第二篇。在“高精度加、减、乘、除”这4种计算中,加法最基础、最简单,乘法稍难,减法更难,除法最难。

我们就接着来研究正整数多位数高精度乘法的计算方式吧。

下面这段话是“原创”性的,它不仅指出LOGO系统自身的一个错误,还与我们只能使用“数组”编程来进行所有的高精度计算有关。

在各种计算机程序设计语言中,“数值”和“字符串”都有严格而明显的界限。但是在LOGO语言中,可能是为了使概念简单化,把“数值”和“字符串”混为一谈,造成编写程序的时候可能出现意想不到的错误。

这里我们要先来讨论一下LOGO系统软件中一个错误。到目前为止还没有见到那个人胆大到声言“LOGO系统本身就有错误!”但是根据林老师的见解:LOGO系统内部在处理“字符串”和“数值”时确实显得有些“傻”。请你在文本区输入以下命令:

? BF "A98765

Result: 98765

? BF "A987654321000

Result: 9.88E+11

BF命令的功能是“输出指定的字或表中,除了第一个字符或元素之外的其他字符或元素”。上面两个例子中,输入的数据显然都是“字符串”。

第一次处理字符串"A98765时输出是正确的。第二次处理字符串"A987654321000时明显出现了错误:LOGO系统把后面剪切下来的字符串又作为数值处理了(输出的是科学记数法的数值)。遗憾是LOGO系统内的这个错误我们根本无法纠正!只能绕道采用特殊的编写程序的方式预防错误的发生。

所以,即使是在显示算式时,我们别无选择,只能从数组中还原输入的数字,而无法用较为简单的BF命令直接“剪取”输入的字符串中的数字。

LOGO系统的“璧玉微瑕”并不妨碍我们发挥它的强大计算功能。

任意位数高精度乘法计算的思路是这样的:

在输入的数字前面加一个字母,使数字作为字符串输入,这样就能处理长数字。

剪切掉开头的字母,把后面的数字先作为字符读出,再用求ASCII值的方式还原成一个个数字并存入数组。

我们估算乘积的位数最多为“被乘数的”数位加上“乘数”的数位。

然后用:I、:J两重循环实现乘法,实际上是模仿手工逐位乘法。

每位乘出来的积马上存储在数组:JC中。

每乘一个数位后,马上处理数组:JC中的进位。这是这个程序中比较抽象的部分。

最后显示输出结果。这才是这个程序的核心部分:我们先设置“标志位”变量:FLAG的值为0,当遇到数组:JC前面的“空位(连续数值为0)”时,越过。当出现第一个不为零的数位时,意味着从这里开始都是有效数位,全部照样输出,直至输出结束。输出有效数位的部分使用了GO—LABEL命令。我们已经一再强调,使用这个命令要小心慎重。但是在这里,GO—LABEL命令起到了其他命令难以替代的作用。

程序的强大功能是不容置疑的。请看计算输出实例。

TO CHENG_N ;任意位数乘法

PR

"请输入一个乘数并在数字前加上1个任意字母:

MAKE "A

READ ;从键盘上读入被乘数

MAKE "A1 COUNT

:A ;测试数的长度

PR

"请输入另一个乘数并在数字前加上1个任意字母:

MAKE "B

READ ;从键盘上读入乘数

MAKE "B1 COUNT

:B ;测试数的长度

MAKE "C

:A1+:B1 ;计算乘积空间长度

MAKE "JA

BYTEARRAY

:A1 ;建立被乘数数存储空间

MAKE "JB

BYTEARRAY

:B1 ;建立乘数的存储空间

MAKE "JC

BYTEARRAY

:C ;建立储存积的存储空间

FOR "I 1

(:A1-1)[ASET :JA :I (ASCII(ITEM :A1-:I+1 :A))-48]

;将被乘数拆位存储

FOR "I 1

(:B1-1)[ASET :JB :I (ASCII(ITEM :B1-:I+1 :B))-48]

;将乘数拆位存储

;%%%%%%%%以下程序段执行逐位乘法计算%%%%%%%%%%

FOR "I 1

(:B1-1)[\

FOR "J 1 (:A1-1)[\

ASET :JC :I+:J-1 (AGET :JC :I+:J-1)+(AGET :JA :J)*(AGET :JB :I)

JW]]

;===============显示输出算式=================

FOR "I 1

(:A1-1)[TYPE AGET :JA :A1-:I] ;显示被乘数

TYPE[*]

FOR "I 1

(:B1-1)[TYPE AGET :JB :B1-:I] ;显示乘数

TYPE[=]

MAKE "FLAG

0

MAKE "N

:C-1 ;共显示:N是数位

LABEL

"LOOP ;输出有效数字程序段

IF :N=0 [PR[]STOP] ;输出数位到此结束

MAKE "S AGET :JC :N ;获得当前位的数值

IF (AND :FLAG=0 :S=0) THEN[MAKE "N :N-1 GO "LOOP]\

ELSE[MAKE "FLAG 1]

IF :FLAG=1 THEN TYPE :S ;对有效位输出显示

MAKE "N

:N-1 ;指向后一个数位

GO

"LOOP ;继续显示其余数位

END

TO JW ;计算乘法进位子程序

FOR "K 1

(:C-1)[IF 9

ASET :JC :K+1 (AGET :JC :K+1)+INT((AGET :JC :K)/10) \

ASET :JC :K (REMAINDER (AGET :JC :K) 10)]]

END

? CHENG_N

请输入一个乘数并在数字前加上1个任意字母:

? A9876543210000087654

请输入另一个乘数并在数字前加上1个任意字母:

?

A678234587654300010099

9876543210000087654*678234587654300010099=6698613211484286042020756127803085217746

? CHENG_N

请输入一个乘数并在数字前加上1个任意字母:

? A100000000

请输入另一个乘数并在数字前加上1个任意字母:

? A100000000000

100000000*100000000000=10000000000000000000

? CHENG_N

请输入一个乘数并在数字前加上1个任意字母:

? A99999999912345

请输入另一个乘数并在数字前加上1个任意字母:

? A1266789008

99999999912345*1266789008=126678900688959609503760

计算的结果表明:再多的数位也能正确计算!

这里是新颖有趣的LOGO、DEV-C++语言之家

欢迎评论 欢迎转载

查找林老师博客最便捷的方法:

在百度、谷歌、搜狗、搜搜、雅虎、有道等搜索引擎中输入

林老师 LOGO

就能找到林老师博客文章了

查阅林老师最新发表文章的链接:

快速检索数百篇博客提高阅读效率的链接:

因网络拥挤“纸条”常不能及时打开查阅。有信息尽量使用“评论”或邮件。

需要LOGO系统文件常用表格工具文件及DEV-C++系统文件的可以发邮件给林老师

声明:

林正山老师发表的文章及照片,媒体、网站或出版物未经本人许可谢绝进行任何形式的删节、改编、重组及转载。

允许个人博客按原文(含图片及附注)进行完整转载,转载时敬请注明本博作者姓名、文章原始出处,并以链接形式标明来源。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值