基础:了解我自己的 Ada 代码。查找除分数以外的整数的数字

BASIC: Understanding my own Ada code. Finding numbers that divide an integer without fractions

我应该编写一个程序来查找所有整除一个数的整数,并且我想出了一个可行的解决方案;不幸的是,由于我不具备编码知识,我不知道为什么 它有效。

基本代码如下:

Get(Number)
A:=1
for X in 1..Number-1 loop
   A:=A+1;
   C:=Number/A;
   if C*A = Number then
      Put(A)
   end if;
end loop;

为了便于阅读,我删除了一些纯 puts,我知道 A 在循环的每一步增加 1,但我不太明白 C 每个循环保留多少.我已经尝试通过打印它来回溯,它在 "number" 上的值 2 和 1 之间,值为 10。我认为它不是 1 或 2,而是 10/1、10/2、10/3、10/4、10/5、10/6 等,这意味着一旦我们到达 if 语句,我们将假设有 10/4*A,其中 A 为 4,中提琴我们得到 10,即使 10 不能被 4 整除。

C是怎么更新的,谁能简单解释一下?

我假设要查找的整数必须是正数。在这种情况下,NumberACX 的类型可以改为 Positive。如果输入不是正数,则会引发 CONSTRAINT_ERROR 异常。这样更安全:异常清楚地表明出了问题,比返回错误的结果要好。

请注意,该程序从不测试 1 是否为有效除数,即使它是。这是因为 A 在循环开始时递增;因为它的起始值为 1,所以第一个检查的值为 2。在任何情况下,最好使用循环变量 X。在您的程序中,它将采用范围从 1Number - 1 的值,包括两端。此外,X 将在循环体内表现得像常量,从而消除了意外覆盖其值的风险。

分配给 C 的值是 Number 除以 A 的结果。鉴于这些变量是整数,除法结果将被截断。对于正数,这相当于 "rounding down" 结果。如果 Number 除以 A,则余数将为零,因此乘法将得到原始值。否则,余数将丢失,因此 C * A 的值将小于 A 的值。

更简单的方法是直接计算两个数的余数,然后检查是否为零。这是结果代码:

procedure Main is
   Number : Positive;
begin
   Get (Number);
   for A in 1 .. Number loop
      if Number rem A = 0 then
         Put (A);
      end if;
   end loop;
end Main;