fortran fortran中文资料网
手气不错
Article

043.conversion_类型转换

数值类型转换根据一个值产生指定类型及kind的新值,原变量的类型和值不会因此改变。intrealcmplx可通过可选的kind参数指定结果种类;dble则把参数转换为双精度实数。转换只作用于传入的表达式,写在运算之前还是之后,可能产生不同的计算结果。

适用场景

类型转换常用于把整数计数参与实数平均、把连续量划入整数档位、统一不同精度数据的计算种类,以及由实部和虚部构造复数。它也能明确表达程序希望在哪一步改变类型,避免赋值时的隐式转换掩盖整数除法或精度变化。

语法结构

integerValue = int(value [, kind])
realValue = real(value [, kind])
doubleValue = dble(value)
complexValue = cmplx(realPart [, imaginaryPart] [, kind])
  • int把实数转换为整数时舍弃小数部分,方向是趋向零,而不是四舍五入或向下取整。
  • real可以转换整数、实数或复数;复数转换为实数时只保留实部。
  • dble返回双精度实数。现代代码需要明确精度时,通常使用real(value, kind=real64)表达得更清楚。
  • cmplx由实部和可选虚部构造复数;处理高精度数据时应显式指定kind

本文代码

! 显式类型转换用于控制计算方式和结果类型。
program conversionDemo
  use iso_fortran_env, only: real64
  implicit none

  integer :: totalPulses, intervals
  real :: convertedAfterDivision, realAverage
  real(real64) :: doubleAverage
  complex(real64) :: impedance

  totalPulses = 25
  intervals = 7

  convertedAfterDivision = real(totalPulses / intervals)
  realAverage = real(totalPulses) / real(intervals)
  doubleAverage = dble(totalPulses) / dble(intervals)
  impedance = cmplx(4.0_real64, 3.0_real64, kind=real64)

  print "(A,F8.4)", "整数除法后再转换:", convertedAfterDivision
  print "(A,F8.4)", "转换后执行实数除法:", realAverage
  print "(A,F12.8)", "双精度平均值:", doubleAverage
  print "(A,I0)", "int(-2.8) = ", int(-2.8)
  print "(A,2F7.2)", "复阻抗的实部与虚部:", impedance
end program conversionDemo

编译运行

(base) hong@hongdeMacBook-Pro 043.conversion % gfortran -Wall -Wextra -std=f2018 exampleConversion.f90
(base) hong@hongdeMacBook-Pro 043.conversion % ./a.out
整数除法后再转换:  3.0000
转换后执行实数除法:  3.5714
双精度平均值:  3.57142857
int(-2.8) = -2
复阻抗的实部与虚部:   4.00   3.00

现象分析

real(totalPulses / intervals)中,括号内的除法最先计算。25和7都是整数,而25可以写成7×3+4,所以整数除法只保留商3并舍弃余数4;随后real(3)得到默认实数3.0,赋给convertedAfterDivision后按F8.4显示为3.0000。转换发生得太晚,已经舍弃的余数无法恢复。

real(totalPulses) / real(intervals)中,转换先得到默认实数25.0和7.0,除法因此按实数规则计算,结果约为3.5714285。F8.4只显示4位小数,并把下一位数字2舍去,所以终端显示3.5714。这里的格式只控制显示,不会把变量内部的值改成3.5714。

dble(totalPulses)dble(intervals)分别得到双精度的25.0和7.0,双精度除法结果约为3.571428571428…。F12.8保留8位小数,第9位是1,因此显示3.57142857。更多数字来自双精度运算与更宽的输出格式共同作用;若源数据已经是发生过舍入的低精度实数,事后转换为双精度仍不能补回丢失的信息。

int(-2.8)舍弃小数部分得到-2,方向是趋近零,而floor(-2.8)才会得到-3。最后,cmplx(4.0_real64, 3.0_real64, kind=real64)构造4.0+3.0i;输出复数时,编辑描述符依次处理其实部4.00和虚部3.00。

核心知识点

  • 转换函数产生新值,不会改变作为参数的原变量。
  • 表达式先按操作数类型计算,再转换最终结果;需要实数除法时必须在整数除法发生前转换。
  • int向零截断,不等同于nintfloorceiling
  • 改变kind不能恢复转换前已经丢失的数值信息;高精度计算应从高精度数据开始。
  • 构造高精度复数时应为cmplx显式指定结果kind

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注