Fortran Coder

标题: Fortran77单精度变量转换为双精度 [打印本页]

作者: GXL    时间: 2022-5-2 10:40
标题: Fortran77单精度变量转换为双精度
本帖最后由 GXL 于 2022-5-2 10:45 编辑

我想问一下Fortran77里有没有函数能够实现将单精度变量转换为双精度变量,
就比如单精度变量x=3.14159,转换为双精度变量就是3.141590000000000,
转换之后后边用0来填充
如果直接赋值或者强制转换的话,后边的尾数不一定是0

作者: Transpose    时间: 2022-5-2 11:15
`real(x,kind=8)`
作者: GXL    时间: 2022-5-2 11:22
Transpose 发表于 2022-5-2 11:15
`real(x,kind=8)`

您好,这种方法我尝试过了,我不知道是我编译器的原因还是Fortran77语言的原因,这种方法在转换精度的过程中,后边并不是全部用0来填充的
作者: Transpose    时间: 2022-5-2 16:51
只能曲线一下
[Fortran] 纯文本查看 复制代码
program main
    implicit none
    real::x
    real(8),external::real4real8
    x=1.234
    write(*,*)x
    write(*,*)real(x,kind=8)
    write(*,*)real4real8(x)
end program

function real4real8(r4)result(r8)
    real,intent(in)::r4
    real(8)::r8
    character(len=15)::str
    write(str,"(ES15.8E2)")r4
    read(str,*)r8
end function real4real8
>    1.23399997   
      1.2339999675750732     
     1.2339999699999999

这个函数可以实现这个效果,但是可能会大幅降低程序效率,自己选择是否使用
作者: vvt    时间: 2022-5-4 22:10
本帖最后由 vvt 于 2022-5-4 22:11 编辑
GXL 发表于 2022-5-2 11:22
您好,这种方法我尝试过了,我不知道是我编译器的原因还是Fortran77语言的原因,这种方法在转换精度的过 ...

实际上,后面是用0填充的,但是它是二进制的 0 填充,输出时转换成10进制,就不是0了。

对于这个问题,首先你要知道。单精度的 x = 3.14159,实际上就不是准确的 3.14159,而是 3.14159011840820......  请理解,浮点数均有误差,而单精度只有6-7位有效数字(严格说约6.9位)

对比一个例子,假如有个文明使用三进制,它们的 0.1(1/3) 表示成十进制就是 0.3333333...
如果我们增大有效位数,变成 0.333333300000000,再转换成三进制,是不是就出现不整位数了?

对于计算机来说,要实现十进制的有效位数保留,效率比较低。大多数时候,我们选择输出时保留一定的位数。
对于你这样的要求,你有两种实现:
1. 你需要保留固定的小数位数,且数字不大。比如你要保留6位小数。
[Fortran] 纯文本查看 复制代码
  real :: x
  real(8) :: y
  y = nint(1.d6*x)/1.d6
  write(*,*) x, y

2. 你要保留固定的有效位数。比如保留7位有效数字。借鉴楼上的方法。(请注意,单精度只有6.9位有效数字,所以你不能保留8位或更多有效数字)
[Fortran] 纯文本查看 复制代码
  y=real4real8(x)
  write(*,*) x, y
  function real4real8(r4)result(r8)
      real,intent(in)::r4
      real(8)::r8
      character(len=15)::str
      write(str,"(ES13.6E2)")r4 !此处的 es13.6 的 6 为保留有效数字-1,即7-1=6
      read(str,*)r8
  end function real4real8

  楼上写的es15.8,显然超过了单精度的有效数字。






欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2