如何使两个足够大的整数(种类=4)加在一起存储为整数(种类=8)?

How to make two large enough integer(kind=4) add together to be stored as integer(kind=8)?

我正在尝试将两个整数 (kind=4) 相加,这两个整数足够大以生成一个整数 (kind=8)。我不确定这是否可行,但我做了一些测试试图让它工作:

!gfortran, gcc version 5.4.0 20160609

program hello
    use iso_fortran_env

    integer, parameter :: i64 = int64
    integer(kind=4) :: a1, a2
    integer(kind=8) :: b1, b2
    integer(kind=8) :: c
    integer(kind=8) :: ugly

    a1 = 2023123123 !kind(4)
    a2 = a1         !kind(4)
    b1 = 2023123123 !kind(8)
    b2 = b1         !kind(8)

    ! sum integers of kind=8 that surely will lead to a kind=8
    c = b1+b2
    print*,c

    ! sum integers of kind=4 and kind=8 that will lead to a kind=8
    c = a1+b1
    print*,c

    ! sum integers of kind=4 which may lead to a kind=8
    c = a1+a2
    print*,c

    ! try to tell gfortran to make a kind(4) behave as a kind(8)
    ! for that operation   
    c = a1+a2_i64
    print*,c

    ! ugly workaround fail - 64 bit 0 on last position
    ugly = 0
    c = a2+a1+ugly
    print*,c

    ! ugly workaround ok - 64 bit 0 on first position
    ugly = 0
    c = ugly+a2+a1
    print*,c

    ! ugly workaround ok - divide in two operations
    c = a1+ugly
    c = c+a2
    print*,c
end program hello

脚本的输出是

4046246246  ! kind(8) + kind(8) = kind(8) -> ok
4046246246  ! kind(4) + kind(8) = kind(8) -> ok, but not sure if it always work
-248721050  ! kind(4) + kind(4) = kind(8) -> NOT OK
2023123072  ! kind(4) + kind(4)_i64 = kind(8) -> NOT OK
-248721050  ! ugly workaround summing 0(kind=8) -> FAIL
4046246246  ! ugly workaround summing 0(kind=8) -> OK
4046246246  ! another ugly work around -> OK

有谁知道如何在没有那个非常丑陋的解决方法的情况下将两个整数(种类=4)相加得到一个整数(种类=8)?

如果 ab 是整数,则表达式 a+b 是整数。如果 ab 属于同一类,则表达式属于该类。如果它们属于不同种类,但其中一个具有更大的十进制指数范围,则表达式属于那种类型。

如果 aba+b 属于同一类型,则不会进行转换。与 a+b 不同种类的操作数(ab)被视为已转换为该种类。

因此,如果您希望结果属于同类 8(假设这是更大范围的结果之一),那么您需要一个(或两个)操作数属于同类 8.如题:

  • b1+b2两个都很善良8;
  • a1+b1,b18,a1转换成那种;
  • a1+a2,两者都是种类 4,未转换,种类 4.
  • 的结果

a+b+c 的情况下,表达式被视为 (a+b)+c:

  • a2+a1+ugly,a2+a1在求值时没有转换,但是求和(a2+a1)+ugly
  • 进行了转换
  • ugly+a2+a1ugly+a2 已将 a2 转换为种类 8,然后将 a1 转换为种类 8 以给出种类的结果8.

所以,如果 a2+a1 对范围无效,那么 a2+a1+ugly 有同样的问题,但是 ugly+a2+a1a1a2 视为种类 8.

最后:

  • int(a1,8)+int(a2,8) 已明确转换为种类 8;
  • int(a1,8)+a2a1+int(a2,8) 具有预期的行为。

所有这些都很丑陋:不要使用 48 之类的类型,尤其是当您有 int64 可用且行为随心所欲时。