Fortran 中的长整型

发布于 2024-09-08 19:56:24 字数 456 浏览 8 评论 0原文

我正在尝试处理大数字(~10^14),并且我需要能够存储它们并迭代该长度的循环,即

n=SOME_BIG_NUMBER
do i=n,1,-1

我尝试了通常的星号表示法,kind=8< /code> 等,但似乎没有任何作用。 然后我检查了巨大的内部函数,代码:

program inttest

print *,huge(1)
print *,huge(2)
print *,huge(4)
print *,huge(8)
print *,huge(16)
print *,huge(32)

end program inttest

在所有情况下都会产生数字 2147483647。这是为什么呢?我在 64 位机器上使用 gfortran (f95)。

如果我需要一个 bignum 库,人们会推荐哪一个?

I'm trying to work with large numbers (~10^14), and I need to be able to store them and iterate over loops of that length, i.e.

n=SOME_BIG_NUMBER
do i=n,1,-1

I've tried the usual star notation, kind=8 etc. but nothing seems to work.
Then I checked the huge intrinsic function, and the code:

program inttest

print *,huge(1)
print *,huge(2)
print *,huge(4)
print *,huge(8)
print *,huge(16)
print *,huge(32)

end program inttest

produces the number 2147483647 in all cases. Why is this? I'm using gfortran (f95) on a 64-bit machine.

If I'm going to need a bignum library, which one do people suggest?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吻泪 2024-09-15 19:56:24

我在 Mac 上使用的 gfortran 版本是 4.3、4.4 和 4.5,支持 8 字节整数。在 Fortran >= 90 中选择变量类型的最佳方法是使用内部函数来指定所需的精度。尝试:

integer, parameter :: LargeInt_K = selected_int_kind (18)
integer (kind=LargeInt_K) :: i, n

获取至少 18 位十进制数字,通常是 8 字节整数。

在gfortran 4.3中,巨大(1_LargeInt_K)输出9223372036854775807。当您编写巨大(1)等时,默认情况下常量是默认整数,这里显然是4个字节,因为巨大返回2147483647。所以有时您需要指定常量,而不仅仅是变量——更常见的是,当人们丢失实常量的有效数字时,这会让人感到困惑,实常量默认为单精度。

另请参阅 Fortran:整数*4 与整数(4) 与整数(kind=4)< /a>

通常 gfortran 的命令名称为 gfortran。 f95 可以是不同的编译器吗?尝试“gfortran -v”和“f95 -v”。

The gfortran versions that I use, 4.3, 4.4 and 4.5 on a Mac, support 8-byte integers. The best way to select a variable type in Fortran >= 90 is to use an intrinsic function to specify the precision that you need. Try:

integer, parameter :: LargeInt_K = selected_int_kind (18)
integer (kind=LargeInt_K) :: i, n

to obtain at least 18 decimal digits, which will typically be a 8-byte integer.

With gfortran 4.3, huge (1_LargeInt_K) outputs 9223372036854775807. When you wrote huge (1), etc., by default the constant was a default integer, here evidently 4-bytes since huge returned 2147483647. So sometimes you need to specify the precision of constants, not just variables -- more commonly this trips people up when they lose significant figures on a real constant, which defaults to single precision.

Also see Fortran: integer*4 vs integer(4) vs integer(kind=4)

Usually gfortran has the command name gfortran. Could f95 be a different compiler? Try "gfortran -v" and "f95 -v".

一抹苦笑 2024-09-15 19:56:24

您误解了 HUGE 函数的精确定义。 HUGE(num) 返回与 num 具有相同种类和类型的最大数字。返回的值也具有与 num 相同的种类和类型。由于所有输入值都是(默认)整数HUGE,因此正确地返回最大的默认大小整数。

HUGE(num) 不会返回 kind=num 的最大整数。 HUGE(num) 也不会返回以 num 字节表示的最大数字。虽然许多编译器使用 integer(kind=4)integer(kind=8) etc 来表示 4 字节和 8 字节整数,但这是不受语言标准的保证,并且不能依赖其可移植性。

@MSB 的答案告诉你如何做你想做的事,我只是插话一些澄清。

You've misunderstood the precise definition of the HUGE function. HUGE(num) returns the largest number with the same kind and type as num. The value returned also has the same kind and type as num. Since all your input values are (default) integers HUGE, correctly, returns the largest default-size integer.

HUGE(num) does not return the largest integer with kind=num. Nor does HUGE(num) return the largest number representable in num bytes. While many compilers use integer(kind=4) and integer(kind=8) etc for 4- and 8-byte integers, this is not guaranteed by the language standard and cannot be relied upon to be portable.

@MSB's answer tells you how to do what you want, I'm just butting in with some clarification.

暖树树初阳… 2024-09-15 19:56:24

摘要:考虑查看编译器选项。

自从我做FORTRAN以来已经很长时间了,我不记得使用过HUGE(),但我稍微看了一下这个。我的 Intel Linux 机器有 gfortran 4.1.2。我发现我必须在打开 -fdefault-integer-8 选项的情况下进行编译才能使其适用于 64 位整数。具体来说,使用以下代码:

      program inttest
      print *, huge(1)
      end program inttest

运行

$ gfortran inttest.for

创建了一个可执行文件,打印:

2147483647

但是,运行:

$ gfortran -fdefault-integer-8 inttest.for

生成一个可执行文件,其输出如下:

9223372036854775807

另外,当我将变量声明为整数*8 并在不使用 -fdefault-integer-8 选项的情况下进行编译时,出现错误。代码:

  program inttest2
  integer*8  test_int
  test_int = 9223372036854775807
  print *, test_int
  end program inttest2

运行

$ gfortran inttest2.for

结果为

在文件 inttest.for:4

<前><代码> test_int = 9223372036854775807
1

错误:整数对于 (1) 处的同类来说太大

但是,当我使用 -fdefault-integer-8 选项编译时,一切正常,并且我得到了一个打印的可执行文件

9223372036854775807

也许还有其他有用的 gfortran 选项,但我没有进一步调查。

当然,这仍然无法得到 10^14,但它可能有助于解释您所看到的结果。

Summary: Consider looking at compiler options.

It's been a l-o-n-g time since I've done FORTRAN, and I don't remember using HUGE(), but I looked at this a little. My Intel Linux machine has gfortran 4.1.2. I found I had to compile with the -fdefault-integer-8 option turned on to make it work for 64 bit integers. Specifically, with this code:

      program inttest
      print *, huge(1)
      end program inttest

running

$ gfortran inttest.for

created an executable which printed:

2147483647

However, running:

$ gfortran -fdefault-integer-8 inttest.for

resulted in an executable which gave the output:

9223372036854775807

Also, when I declared a variable as integer*8 and compiled without the -fdefault-integer-8 option, I got an error. The code:

  program inttest2
  integer*8  test_int
  test_int = 9223372036854775807
  print *, test_int
  end program inttest2

running

$ gfortran inttest2.for

resulted in

In file inttest.for:4

  test_int = 9223372036854775807  
                               1 

Error: Integer too big for its kind at (1)

However, things worked fine when I compiled with the -fdefault-integer-8 option and I got an executable which printed

9223372036854775807

Maybe there are other gfortran options which would be useful, but I didn't investigate further.

Granted, this still doesn't get you 10^14, but it may help explain the results you saw.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文