Fortran Coder

查看: 5970|回复: 4
打印 上一主题 下一主题

[数值问题] Fortran77单精度变量转换为双精度

[复制链接]

10

帖子

4

主题

0

精华

入门

F 币
53 元
贡献
28 点
跳转到指定楼层
楼主
发表于 2022-5-2 10:40:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 GXL 于 2022-5-2 10:45 编辑

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

168

帖子

2

主题

1

精华

大师

Vim

F 币
1021 元
贡献
486 点

规矩勋章

沙发
发表于 2022-5-2 11:15:00 | 只看该作者
`real(x,kind=8)`

10

帖子

4

主题

0

精华

入门

F 币
53 元
贡献
28 点
板凳
 楼主| 发表于 2022-5-2 11:22:29 | 只看该作者

您好,这种方法我尝试过了,我不知道是我编译器的原因还是Fortran77语言的原因,这种方法在转换精度的过程中,后边并不是全部用0来填充的

168

帖子

2

主题

1

精华

大师

Vim

F 币
1021 元
贡献
486 点

规矩勋章

地板
发表于 2022-5-2 16:51:28 | 只看该作者
只能曲线一下
[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

这个函数可以实现这个效果,但是可能会大幅降低程序效率,自己选择是否使用

954

帖子

0

主题

0

精华

大师

F 币
184 元
贡献
75 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
5#
发表于 2022-5-4 22:10:34 | 只看该作者
本帖最后由 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,显然超过了单精度的有效数字。

您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-12-25 08:58

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表