Ada 中 Sum 的实现
1)
Sum := 0;
for J in 1 .. N loop
Sum := Sum + J;
end loop;
2)
Sum := ((N + 1) * N) / 2;
我读到第一个(左)解决方案更“通用” - 适用比第二个(右)解决方案更广泛的值。 “一般”是什么意思——可以计算而不会溢出?
1)
Sum := 0;
for J in 1 .. N loop
Sum := Sum + J;
end loop;
2)
Sum := ((N + 1) * N) / 2;
I've read that the first(left) solution is more "general" - applicable to a wide range of values - than second(right) solution. What does "general" mean - can be computed without overflow?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为“更通用”必须意味着“可以在更大范围的数字的情况下进行计算而不会溢出”。
(2) 中的中间乘积将在 2^31 - 1 处溢出(对于大多数现代机器上将得到的 32 位整数),这意味着最大的合法结果将稍小比 2^30 - 1. (1) 会让你继续几乎同样的距离(如果你能等那么久!)
这个程序探索了极限:
如果你使用 gnatmake -gnato summation.adb 进行编译> 和运行它,它以“如果你省略了
-gnato
”结尾,这样 GNAT 就不会进行数字溢出检查(一个令人遗憾的默认值,我记得是为了提高效率而选择的),这种情况会发生:
我想你可以得到在进行乘法之前,通过将
N
和N + 1
中的偶数(显然必须是偶数)除以 2 来获得更长的范围。这并不是真正的 Ada 问题(尽管
-gnato
比其他语言更容易发现问题),而且它当然不是阶乘!可以修改标题吗?I think “more general” must mean “can be computed without overflow for a larger range of numbers”.
The intermediate product in (2) will overflow at 2^31 - 1 (for a 32-bit
Integer
as you will get on most modern machines), which means that the largest legal result will be somewhat less than 2^30 - 1. (1) will let you continue almost as far again (if you can wait that long!)This program explores the limits:
and if you compile with
gnatmake -gnato summation.adb
and run it it ends withIf you leave out the
-gnato
, so that GNAT doesn’t do numeric overflow checks (a regrettable default, chosen as I remember for efficiency) this happens:I suppose you could get the longer range by dividing whichever of
N
andN + 1
was even (one clearly must be!) by 2 before doing the multiplication.This isn’t really an Ada problem (though
-gnato
makes it easier to see when things go wrong than might happen with some other languages), and it’s certainly not a factorial! Is it possible to edit the title?撇开语法不谈(我们是从概念上而不是语法上看待这个问题),
因为我们在这里真正讨论的是求和,所以我会对此做出回应。
我的第一个猜测为什么左边更通用,可能是因为大多数人忘记了 i 从 1 到 n 求和的捷径。因为两个方程在数学上是等价的。您的系统上哪一个速度更快?
人们需要完成将 1 到 n 中的每个数字相加的繁琐任务。
如果你看一下维基百科上的求和文章,你会发现从1到100的求和需要99次加法。
http://en.wikipedia.org/wiki/Summation
而右边的等式(快捷方式)只会执行除法、乘法和一次加法。
我的第二个猜测是,在某些(也许更多)情况下,进行添加会更快......这是一个依赖于系统的情况,以及依赖于问题的情况,所以我认为这种可能性较小。
您能否提供有关此文档的参考信息,上下文会非常有帮助。
Syntax aside (we're looking at this conceptually not syntatically),
Since we are really talking about summations here, I'll respond to that.
My first guess why the left is more general is possibly because most people forget that there is a shortcut to a summation of i from 1 to n. Since both equations are mathematically equivalent. Which one is the faster on your system?
One does the tedious task of adding each individual number from 1 to n.
If you take a look at the summation article on wikipedia, you will see that the summation from 1-100 requires 99 additions.
http://en.wikipedia.org/wiki/Summation
Whereas the equation on the right (the shortcut) will only do a division and a multiplication and a single addition.
My second guess is perhaps in certain (maybe more) situations it would be faster to do n additions....that's a system dependent situation, as well as problem dependent, so I think that's less likely.
Could you give a reference as to this document, context would be really helpful.