Я думаю, что «более общее» должно означать «может быть вычислено без переполнения для большего диапазона чисел».
Промежуточный продукт в (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, прежде чем выполнять умножение.
На самом деле это не проблема Ады (хотя -gnato
легче увидеть, когда что-то пойдет не так, чем это может случиться с некоторыми другими языками), и это определенно не факториал! Можно ли отредактировать заголовок?
person
Simon Wright
schedule
11.01.2012
:=
без пробела посередине. Что-то не так с (1),Sum
каждый раз перезаписывается и не дает правильного значения ни для одного ввода. (2) случайно дает правильное значение для ввода 3. Я думал, вы просто шутите, но я вижу, вы уже задавали дельные вопросы... - person Simon Wright   schedule 11.01.2012:=
представляет собой одиночный токен, и вам не хватает многих точек с запятой.) - person Keith Thompson   schedule 11.01.2012Sum := 0; for J in 1 .. N loop Sum := Sum + J; end loop;
Ой, простите! Я скопировал из PDF. Поэтому это было не правильно. - person stardust   schedule 11.01.2012