Sum := 0;
for J in 1 .. N loop
Sum := Sum + J;
end loop;
2)
Sum := ((N + 1) * N)/2;
我读过的第一(左)解决方案更 “一般” - 适用于比第二个(右)解决方案的值范围很广。 “一般”意味着什么 - 可以不溢出地计算出来?
Sum := 0;
for J in 1 .. N loop
Sum := Sum + J;
end loop;
2)
Sum := ((N + 1) * N)/2;
我读过的第一(左)解决方案更 “一般” - 适用于比第二个(右)解决方案的值范围很广。 “一般”意味着什么 - 可以不溢出地计算出来?
我觉得“比较一般”必定意味着“可以不计算为溢出更大范围的数字”。
(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
我想你可以得到更长的范围通过在执行乘法之前将N
和N + 1
中的任何一个除以2(甚至必须是!)乘以2。
这不是一个真正的Ada问题(虽然-gnato
可以更容易地看出事情发生错误时可能会发生的其他语言),但这绝对不是一个因子!是否可以编辑标题?
谢谢,我明白了。 – stardust 2012-01-11 00:19:10
抛开语法(我们正在寻找这个概念不syntatically),
因为我们真的在谈论求和这里,我要作出回应。
我第一次的猜测,为什么左边是更普遍的是可能是因为大多数人都忘了,有一个捷径,我从1到n的总和。由于两个方程在数学上是等价的。你的系统中哪一个更快?
一个确实将每个个体数从1到n的乏味的任务。
如果你看看维基百科上的文章总结,你会看到,从1-100的总和,需要99次加法。 http://en.wikipedia.org/wiki/Summation
而右侧的公式(快捷键)只会进行除法和乘法以及单一加法。
我的第二个猜测可能是在某些(也许更多)的情况下它会更快做N添加....这是一个依赖于系统的情况,以及相关的问题,所以我认为这是不太可能。
可不可以给一个参考,以这个文件,背景将是很有益。
Ada的赋值运算符是':='*,中间没有空格。 (1)有问题,每次都会覆盖“Sum”,并且它不会为任何输入提供正确的值。 (2)意外地为3的输入提供了正确的值。我以为你只是在开玩笑,但我看到你之前已经提出了明智的问题...... – 2012-01-10 20:25:50
这些都没有计算阶乘函数,也没有语法正确的Ada。 (':='运算符是一个单一的标记,并且缺少大量的分号。) – 2012-01-10 20:26:50
'Sum:= 0; for J in 1 .. N loop Sum:= Sum + J; end loop;' 哦,对不起!我从PDF复制。因此它是不正确的。 – stardust 2012-01-10 21:14:01