Types 帮助传递FORTRAN整数会将它们转换为不准确的浮点?
当我创建一个标量整数s并将其传递给一个子例程时,它的值被转换为一个浮点值,非常不准确。例如,如果我设置s=2并调用print_my_ints进行写入,它将输出到控制台,它的值显示为2.80259693E-45。其他标量整数的行为类似,但s=0的情况除外,在这种情况下,输出为0.0000000。但即使这样,这仍然是错误的,因为整数显然不应该显示小数点和尾数。这不是一个输出格式问题,因为我可以让其他整数在本地显示时正确显示 关于这里发生的事情有什么线索吗?是否需要在子例程定义中强制参数数据类型?这能做到吗 示例代码:Types 帮助传递FORTRAN整数会将它们转换为不准确的浮点?,types,integer,fortran,argument-passing,subroutine,Types,Integer,Fortran,Argument Passing,Subroutine,当我创建一个标量整数s并将其传递给一个子例程时,它的值被转换为一个浮点值,非常不准确。例如,如果我设置s=2并调用print_my_ints进行写入,它将输出到控制台,它的值显示为2.80259693E-45。其他标量整数的行为类似,但s=0的情况除外,在这种情况下,输出为0.0000000。但即使这样,这仍然是错误的,因为整数显然不应该显示小数点和尾数。这不是一个输出格式问题,因为我可以让其他整数在本地显示时正确显示 关于这里发生的事情有什么线索吗?是否需要在子例程定义中强制参数数据类型?这能
PROGRAM print_int
INTEGER s
s = 2
CALL print_my_int(s)
END PROGRAM print_int
SUBROUTINE print_my_int(x)
WRITE(*,*) x
END SUBROUTINE print_my_int
结果输出:
2.80259693E-45
好吧,早熟的帖子,但我会留给遇到同样问题的人。我不习惯FORTRAN中强制参数类型的语法。在子例程定义中,参数的数据类型位于名称和参数列表下方。如果未包含,GNU编译器不会发出警告或嘎嘎声。我想默认情况下,它会将其转换为其他类型。所以,我上面的例子应该是这样的
PROGRAM print_int
INTEGER s
s = 2
CALL print_my_int(s)
END PROGRAM print_int
SUBROUTINE print_my_int(x)
INTEGER x
WRITE(*,*) x
END SUBROUTINE print_my_int
好吧,早熟的帖子,但我会留给遇到同样问题的人。我不习惯FORTRAN中强制参数类型的语法。在子例程定义中,参数的数据类型位于名称和参数列表下方。如果未包含,GNU编译器不会发出警告或嘎嘎声。我想默认情况下,它会将其转换为其他类型。所以,我上面的例子应该是这样的
PROGRAM print_int
INTEGER s
s = 2
CALL print_my_int(s)
END PROGRAM print_int
SUBROUTINE print_my_int(x)
INTEGER x
WRITE(*,*) x
END SUBROUTINE print_my_int
不是什么新东西,只是想通过提供一些不适合注释的代码来指出接口的使用: 如上所述,您可以在声明部分的开始处到处放置implicit none,或者您可以在程序中放置一个使用子例程的接口,然后编译器将抛出类型不匹配错误:
PROGRAM print_int
INTERFACE
SUBROUTINE print_my_int(x)
END SUBROUTINE
END INTERFACE
INTEGER s
s = 2
CALL print_my_int(s)
END PROGRAM print_int
SUBROUTINE print_my_int(x)
WRITE(*,*) x
END SUBROUTINE print_my_int
不是什么新东西,只是想通过提供一些不适合注释的代码来指出接口的使用: 如上所述,您可以在声明部分的开始处到处放置implicit none,或者您可以在程序中放置一个使用子例程的接口,然后编译器将抛出类型不匹配错误:
PROGRAM print_int
INTERFACE
SUBROUTINE print_my_int(x)
END SUBROUTINE
END INTERFACE
INTEGER s
s = 2
CALL print_my_int(s)
END PROGRAM print_int
SUBROUTINE print_my_int(x)
WRITE(*,*) x
END SUBROUTINE print_my_int
另一个比@steabert更简单的扩展评论:
PROGRAM print_int
INTEGER s
s = 2
CALL print_my_int(s)
CONTAINS
SUBROUTINE print_my_int(x)
WRITE(*,*) x
END SUBROUTINE print_my_int
END PROGRAM print_int
通过在程序中包含子例程,可以强制编译器生成显式接口,从而节省3行代码。通过在子例程中隐式声明x,编译器可以发现错误。另一个扩展注释,比@steabert的注释更简单:
PROGRAM print_int
INTEGER s
s = 2
CALL print_my_int(s)
CONTAINS
SUBROUTINE print_my_int(x)
WRITE(*,*) x
END SUBROUTINE print_my_int
END PROGRAM print_int
通过在程序中包含子例程,可以强制编译器生成显式接口,从而节省3行代码。通过在子例程中隐式声明x,编译器可以发现错误。如果将参数名从x更改为i或j,也可以工作,因为FORTRAN具有基于变量名初始字符的类型推断。但不要那样做,这是一种坏习惯。谢谢你,先生。这是一个方便的提示,但我会注意避免这种弊端。如果你想让编译器在非声明变量上阻塞,最好在每个程序/子例程的开头使用隐式none语句。如果可能的话,请给出一些友好的建议。始终使用隐式无,它可以为您节省大量头发—在这种情况下,您不会将头发撕下来。还可以阅读一本关于Fortran的书,而不是一本互联网教程,阅读关于范围界定问题的一章——它几乎总是在程序过程下——函数和子程序。将程序拆分为模块也有助于避免此类问题,不完全是此类问题,而是类似的问题。请记住,上帝是真实的,除非另有明确声明:-如果将参数名称从x更改为i或j,它也会起作用,因为FORTRAN具有基于变量名初始字符的类型推断。但不要那样做,这是一种坏习惯。谢谢你,先生。这是一个方便的提示,但我会注意避免这种弊端。如果你想让编译器在非声明变量上阻塞,最好在每个程序/子例程的开头使用隐式none语句。如果可能的话,请给出一些友好的建议。始终使用隐式无,它可以为您节省大量头发—在这种情况下,您不会将头发撕下来。还可以阅读一本关于Fortran的书,而不是一本互联网教程,阅读关于范围界定问题的一章——它几乎总是在程序过程下——函数和子程序。将程序拆分为模块也有助于避免此类问题,不完全是此类问题,而是类似的问题。请记住,上帝是真实的,除非另有明确声明:-