选择取整方式
要更改程序中的舍入方式,您可以调用 fpsets 和 fpgets 例程,这些例程使用在包含文件 /usr/include/fpdt.h 和 /usr/include/fpdc.h中定义的名为 fpstat的逻辑数组。 fpstat 数组元素对应于浮点状态和控制寄存器中的位。 它们对应于 FPSCR 位的下半部。
对于浮点舍入控制,数组元素 fpstat(fprn1) 和 fpstat(fprn2) 按下表中的指定进行设置:
| fpstat(fprn1) | fpstat(fprn2) | 已启用取整方式 |
|---|---|---|
| .true. | .true. | 向负无穷大舍入。 |
| .true. | .false. | 向正无穷大舍入。 |
| .false. | .true. | 向零舍入。 |
| .false. | .false. | 舍入到最近。 |
例如:
program fptest
include 'fpdc.h'
call fpgets( fpstat ) ! Get current register values.
if ( (fpstat(fprn1) .eqv. .false.) .and. +
(fpstat(fprn2) .eqv. .false.)) then
print *, 'Before test: Rounding mode is towards nearest'
print *, ' 2.0 / 3.0 = ', 2.0 / 3.0
print *, ' -2.0 / 3.0 = ', -2.0 / 3.0
end if
call fpgets( fpstat ) ! Get current register values.
fpstat(fprn1) = .TRUE. ! These 2 lines mean round towards
fpstat(fprn2) = .FALSE. ! +INFINITY.
call fpsets( fpstat )
r = 2.0 / 3.0
print *, 'Round towards +INFINITY: 2.0 / 3.0= ', r
call fpgets( fpstat ) ! Get current register values.
fpstat(fprn1) = .TRUE. ! These 2 lines mean round towards
fpstat(fprn2) = .TRUE. ! -INFINITY.
call fpsets( fpstat )
r = -2.0 / 3.0
print *, 'Round towards -INFINITY: -2.0 / 3.0= ', r
end
! This block data program unit initializes the fpstat array, and so on.
block data
include 'fpdc.h'
include 'fpdt.h'
endOpen XL Fortran 还提供了若干过程,允许您直接控制处理器的浮点状态和控制寄存器。 这些过程比 fpsets 和 fpgets 子例程更高效,因为它们映射到直接处理浮点状态和控制寄存器 (fpscr) 的内联机器指令中。
Open XL Fortran 提供 xlf_fp_util 模块中的 get_round_mode() 和 set_round_mode() 过程。 这些过程分别返回并设置当前二进制浮点取整方式。
例如:
program fptest
use, intrinsic :: xlf_fp_util
integer(fpscr_kind) old_fpscr
if ( get_round_mode() == fp_rnd_rn ) then
print *, 'Before test: Rounding mode is towards nearest'
print *, ' 2.0 / 3.0 = ', 2.0 / 3.0
print *, ' -2.0 / 3.0 = ', -2.0 / 3.0
end if
old_fpscr = set_round_mode( fp_rnd_rp )
r = 2.0 / 3.0
print *, 'Round towards +infinity: 2.0 / 3.0 = ', r
old_fpscr = set_round_mode( fp_rnd_rm )
r = -2.0 / 3.0
print *, 'Round towards -infinity: -2.0 / 3.0 = ', r
end
Open XL Fortran 提供了 ieee_arithmetic 模块中的 ieee_get_rounding_mode() 和 ieee_set_rounding_mode() 过程。 这些可移植过程分别检索并设置当前浮点取整方式。
例如:
program fptest
use, intrinsic :: ieee_arithmetic
type(ieee_round_type) current_mode
call ieee_get_rounding_mode( current_mode )
if ( current_mode == ieee_nearest ) then
print *, 'Before test: Rounding mode is towards nearest'
print *, ' 2.0 / 3.0 = ', 2.0 / 3.0
print *, ' -2.0 / 3.0 = ', -2.0 / 3.0
end if
call ieee_set_rounding_mode( ieee_up )
r = 2.0 / 3.0
print *, 'Round towards +infinity: 2.0 / 3.0 = ', r
call ieee_set_rounding_mode( ieee_down )
r = -2.0 / 3.0
print *, 'Round towards -infinity: -2.0 / 3.0 = ', r
end备注信息:
- 扩展精度浮点值必须仅在舍入到最近的方式下使用。
- 对于线程安全和重新连接,包含文件
包含受触发器常量 IBMT保护的 THREADLOCAL 伪指令。 缺省情况下,调用命令 xlf_r, xlf90_r, xlf95_r, xlf2003_r, 和 xlf2008_r 打开 -qthreaded 编译器选项,这反过来意味着触发常量 IBMT。 如果要将文件/usr/include/fpdc.h包含在并非旨在线程安全的代码中,请不要将 IBMT 指定为触发器常量。/usr/include/fpdc.h - 编译将取整方式更改为 -qfloat=rrm 的程序。
有关 FPSCR 寄存器中对应于 fpstat 阵列元素的位的更多信息,请参阅 POWERstation and POWERserver Hardware Technical Reference-General Information。