增加整数大小/避免整数溢出?

increase integer size / avoid integer overflow?

在 FORTRAN 中,我可以将整数的声明更改为 integer(kind = 8) 并且它有效。

如何在 Ada 中做类似的事情?

我的程序正在处理非常大的数字,当它变得非常大时它会给我一些负数。

我试过:

with ada.text_io; use ada.text_io;
with ada.integer_text_io; use ada.integer_text_io;
with multiplication_io; use multiplication_io;

procedure multiplication is

    type unsigned is range 0 .. 2**32-1;
    multiplier, multiplicand : unsigned;
begin

    put_line("multiplier?");
    get(multiplier);

end multiplication;

但我收到以下错误:

multiplication.adb:12:05: no candidate interpretations match the actuals:
multiplication.adb:12:05: missing argument for parameter "Item" in call to "get" declared at a-tiinio.ads:70, instance at a-inteio.ads:18
multiplication.adb:12:05: missing argument for parameter "Item" in call to "get" declared at a-tiinio.ads:50, instance at a-inteio.ads:18
multiplication.adb:12:05: missing argument for parameter "Item" in call to "get" declared at a-textio.ads:239
multiplication.adb:12:05: missing argument for parameter "Item" in call to "get" declared at a-textio.ads:205
multiplication.adb:12:09: expected type "Standard.Integer"
multiplication.adb:12:09: found type "unsigned" defined at line 7
multiplication.adb:12:09:   ==> in call to "Get" at a-tiinio.ads:55, instance at a-inteio.ads:18
multiplication.adb:12:09:   ==> in call to "Get" at a-textio.ads:240
multiplication.adb:12:09:   ==> in call to "Get" at a-textio.ads:206
gnatmake: "src/multiplication.adb" compilation error
Makefile:18: recipe for target 'default' failed
make: *** [default] Error 4

定义一个范围为0到2**32的整数类型:

type My_Integer is range 0 .. 2**32;

您不需要指定它派生自哪个预定义整数类型;让编译器为您处理。

顺便说一下,您可能想要:

type My_Integer is range 0 .. 2**32-1;

如果它应该占用32位。

您还需要决定是要普通整数类型还是模块化类型。无论您选择什么范围,它仍然有可能溢出,其结果取决于您是否禁用了范围检查。

对于您现在添加到问题中的示例代码,您需要为您的整数类型实例化 Integer_IO

package Unsigned_IO is new Ada.Text_IO.Integer_IO(unsigned);
-- ...
Unsigned_IO.Get(Multiplier);

你不告诉我们 multiplication_io 是什么;但是如果要 i/o 与乘法相关(无论可能是什么!)你 可能 想要添加 use multiplication_io;.

我试过了

with Ada.Text_IO; use Ada.Text_IO;

procedure Multiplication is

   type Unsigned is range 0 .. 2**32-1;
   Multiplier, Multiplicand : Unsigned;

   package Multiplication_IO is new Ada.Text_IO.Integer_IO (Unsigned);
   use Multiplication_IO;

begin

   Put_Line("multiplier?");
   Get(Multiplier);

end Multiplication;

它编译得很好。

当然,我的 Multiplication_IO 应该被称为 Unsigned_IO,正如@KeithThompson 所建议的。关键是,不管它叫什么,都是为了 Unsigned 值;它不适用于 Integer。你写了 get(multiplier);,而编译器唯一能看到的 getInteger_Text_IO 中的那个 Integer。您需要阅读有关 Ada 和类型的内容! adaic.org 的其中一本电子书将是一个开始。

对于更大的数字,您可以查看 Long_Integer:在 GNAT 中,它是

type Long_Integer is range -(2 **63) .. +(2 **63 - 1);
for Long_Integer'Size use 64;

如果计算的 结果 符合常规整数(但计算可能会溢出),您可能需要查看 GNAT 溢出消除 (http://docs.adacore.com/gnat_ugn-docs/html/gnat_ugn/gnat_ugn/gnat_and_program_execution.html#management-of-overflows-in-gnat)。例如。使用 pragma Overflow_Mode(常规 => 消除);