2012-01-10 63 views
1

1)Ada中实现总和的

Sum := 0; 
for J in 1 .. N loop 
Sum := Sum + J; 
end loop; 

2)

Sum := ((N + 1) * N)/2; 

enter image description here

我读过的第一(左)解决方案更 “一般” - 适用于比第二个(右)解决方案的值范围很广。 “一般”意味着什么 - 可以不溢出地计算出来?

+0

Ada的赋值运算符是':='*,中间没有空格。 (1)有问题,每次都会覆盖“Sum”,并且它不会为任何输入提供正确的值。 (2)意外地为3的输入提供了正确的值。我以为你只是在开玩笑,但我看到你之前已经提出了明智的问题...... – 2012-01-10 20:25:50

+1

这些都没有计算阶乘函数,也没有语法正确的Ada。 (':='运算符是一个单一的标记,并且缺少大量的分号。) – 2012-01-10 20:26:50

+0

'Sum:= 0; for J in 1 .. N loop Sum:= Sum + J; end loop;' 哦,对不起!我从PDF复制。因此它是不正确的。 – stardust 2012-01-10 21:14:01

回答

4

我觉得“比较一般”必定意味着“可以不计算为溢出更大范围的数字”。

(2)中的中间产品将在2^31-1溢出(对于32位Integer,因为您会在大多数现代机器上使用),这意味着最大的法律结果将小于2^30 - 1(1)将让你继续几乎再远

这个节目探讨的限制:

with Ada.Exceptions; 
with Ada.Text_IO; use Ada.Text_IO; 
procedure Summation is 
    N : Integer := 1; 
    Sum : Integer; 
begin 
    loop 
     Put (Integer'Image (N) & " => "); 
     Sum := ((N + 1) * N)/2; 
     Put_Line (Integer'Image (Sum)); 
     N := N + 1; 
    end loop; 
exception 
    when E : others => 
     Put_Line (Ada.Exceptions.Exception_Message (E)); 
end Summation; 

,如果你有gnatmake -gnato summation.adb编译并运行它(如果你能等那么久!)它结束于

46337 => 1073581953 
46338 => 1073628291 
46339 => 1073674630 
46340 => 1073720970 
46341 => summation.adb:9 overflow check failed 

如果你离开了-gnato,使GNAT没有做数字溢出检查(一个令人遗憾的默认,因为我记得效率选择)发生这种情况:

46337 => 1073581953 
46338 => 1073628291 
46339 => 1073674630 
46340 => 1073720970 
46341 => -1073716337 
46342 => -1073669995 
46343 => -1073623652 

我想你可以得到更长的范围通过在执行乘法之前将NN + 1中的任何一个除以2(甚至必须是!)乘以2。

这不是一个真正的Ada问题(虽然-gnato可以更容易地看出事情发生错误时可能会发生的其他语言),但这绝对不是一个因子!是否可以编辑标题?

+0

谢谢,我明白了。 – stardust 2012-01-11 00:19:10

2

抛开语法(我们正在寻找这个概念不syntatically),

因为我们真的在谈论求和这里,我要作出回应。

我第一次的猜测,为什么左边是更普遍的是可能是因为大多数人都忘了,有一个捷径,我从1到n的总和。由于两个方程在数学上是等价的。你的系统中哪一个更快?

一个确实将每个个体数从1到n的乏味的任务。

如果你看看维基百科上的文章总结,你会看到,从1-100的总和,需要99次加法。 http://en.wikipedia.org/wiki/Summation

而右侧的公式(快捷键)只会进行除法和乘法以及单一加法。

我的第二个猜测可能是在某些(也许更多)的情况下它会更快做N添加....这是一个依赖于系统的情况,以及相关的问题,所以我认为这是不太可能。

可不可以给一个参考,以这个文件,背景将是很有益。