Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Io I/O中的数值表达式_Io_Fortran - Fatal编程技术网

Io I/O中的数值表达式

Io I/O中的数值表达式,io,fortran,Io,Fortran,我正在寻找一种用Fortran阅读数字表达式的方法 用数字表示,我指的是dsqrt(0.5d0)/3.d0+1.d0或其他什么,而不是翻译后的1.235…真实版本 我是说读书 open(unit=UnitNumber,file=“FileName”) 读取(单元号,*).. 我试图在reading语句中定义格式,例如read(unitNumber,“(15F24.17)”),但它没有帮助。我是 我想知道我是否只能在内部定义real(8),参数::dsqrt(0.5d0)/3.d0+1.d0 也许

我正在寻找一种用Fortran阅读数字表达式的方法

用数字表示,我指的是
dsqrt(0.5d0)/3.d0+1.d0
或其他什么,而不是翻译后的
1.235…
真实版本

我是说读书

open(unit=UnitNumber,file=“FileName”)
读取(单元号,*)..

我试图在reading语句中定义格式,例如
read(unitNumber,“(15F24.17)”)
,但它没有帮助。我是

我想知道我是否只能在内部定义
real(8),参数::dsqrt(0.5d0)/3.d0+1.d0


也许使用
格式
语法会有所帮助?

不,在Fortran或任何相关编程语言中都没有类似的东西。有用于类似目的的特定库(在Fortran中不一定太多)


我一点也不清楚你为什么要这样做,以及你打算如何使用这样的表达方式。它必须是某种特定的类型,并且您需要特定的子例程来计算这样的表达式。

不,在Fortran或任何相关编程语言中都没有类似的东西。有用于类似目的的特定库(在Fortran中不一定太多)


我一点也不清楚你为什么要这样做,以及你打算如何使用这样的表达方式。它必须是某种特定的类型,并且您需要特定的子例程来计算这样的表达式。

正如@agentp所建议的,Python和Julia等解释语言可以将字符串直接解析为一段代码,因此利用这样的功能可能很方便。但是,如果您确实需要在Fortran中实现相同的目标,另一种方法(用最少的努力!)可能只是在这些语言中调用eval(),例如:

module util
    use iso_fortran_env, only: dp => real64
    implicit none
contains

subroutine eval( expr, ans, x, y )
    character(*), intent(in)       :: expr
    real(dp), intent(out)          :: ans
    real(dp), intent(in), optional :: x, y
    character(len(expr)+200) cmd, sx, sy
    integer u

    sx = "" ; sy = ""
    if ( present(x) ) write( sx, "(' x = ', es25.15, ' ; ')" ) x
    if ( present(y) ) write( sy, "(' y = ', es25.15, ' ; ')" ) y

    write( cmd, "(a)" ) &
            "python -c ""from __future__ import print_function, division ; " // &
            "from math import * ; " // trim(sx) // trim(sy) // &
            "print( eval( '" // trim(expr) // "' ))"" > tmp.dat"

    call system( trim( cmd ) )

    open( newunit=u, file="tmp.dat", status="old" )
    read( u, * ) ans
    close( u )

    call system( "rm -f tmp.dat" )
end subroutine

end module

program main
    use util, only: dp, eval
    implicit none
    character(200) str
    real(dp) ans

    str = "sqrt( 2.0 ) + 1000.0"
    call eval( str, ans )
    print *, "ans = ", ans

    str = "acos( x ) + 2000.0"
    call eval( str, ans, x= -1.0_dp )
    print *, "ans = ", ans

    str = "10 * x + y"
    call eval( str, ans, x= 1.0_dp, y= 2.0_dp )
    print *, "ans = ", ans
end program
结果:

$ gfortran test.f90    # gfortran >=5 is recommended
$ ./a.out
 ans =    1001.4142135623731
 ans =    2003.1415926535899
 ans =    12.000000000000000

更具体地说,上面的代码只是通过system()调用Python中的内置eval()函数。但这不是很有效,因为结果值一旦写入外部文件(以及调用Python本身的开销)。因此,如果效率很重要,那么最好使用更具体的第三方库,或者为了方便起见,直接使用解释语言。(如果计算要求不太高,我建议采用后一种方法,因为这样可以节省大量的编码时间……)

Python:

from __future__ import print_function, division
from math import *
str = input( "Input an expression: " )
x = 1.0
y = 2.0
print( eval( str ) )   # if you type "x + 10 * y" in the prompt, you get 21
朱莉娅:

println( "Input an expression: " )
str = readline()
x = 1.0
y = 2.0
println( eval( parse( str ) ) )

[编辑]

如果可以使用
system()
并编写外部文件,另一个选项可能是只编写一个包含要计算的表达式的小型Fortran代码,通过system()编译并运行它,通过外部文件获得结果。例如,如果我们将上述代码中的两行(
write(cmd),(a)…
system(trim(cmd))
)替换为以下内容,则会得到相同的结果。如果我们想让代码完全用Fortran编写,只需很少的修改,这可能很有用

    open( newunit=u, file="tmp.f90" )
    write( u, "(a)" ) "implicit none"
    write( u, "(a)" ) "real :: x, y"
    write( u, "(a)" ) trim(sx)
    write( u, "(a)" ) trim(sy)
    write( u, "(a)" ) "write(*,'(e30.20)') " // trim(expr)
    write( u, "(a)" ) "end"
    close( u )

    call system( "gfortran -fdefault-real-8 -ffree-line-length-none tmp.f90 && ./a.out > tmp.dat" )
         ! Assuming bash on Linux or Mac (x86_64).
         ! -fdefault-real-8 is attached to promote 1.0 etc to 8-byte floating-point values.

    call system( "rm -f tmp.f90" )

正如@agentp所建议的,Python和Julia等解释语言可以将字符串直接解析为一段代码,因此利用这样的功能可能会方便您的使用。但是,如果您确实需要在Fortran中实现相同的目标,另一种方法(用最少的努力!)可能只是在这些语言中调用eval(),例如:

module util
    use iso_fortran_env, only: dp => real64
    implicit none
contains

subroutine eval( expr, ans, x, y )
    character(*), intent(in)       :: expr
    real(dp), intent(out)          :: ans
    real(dp), intent(in), optional :: x, y
    character(len(expr)+200) cmd, sx, sy
    integer u

    sx = "" ; sy = ""
    if ( present(x) ) write( sx, "(' x = ', es25.15, ' ; ')" ) x
    if ( present(y) ) write( sy, "(' y = ', es25.15, ' ; ')" ) y

    write( cmd, "(a)" ) &
            "python -c ""from __future__ import print_function, division ; " // &
            "from math import * ; " // trim(sx) // trim(sy) // &
            "print( eval( '" // trim(expr) // "' ))"" > tmp.dat"

    call system( trim( cmd ) )

    open( newunit=u, file="tmp.dat", status="old" )
    read( u, * ) ans
    close( u )

    call system( "rm -f tmp.dat" )
end subroutine

end module

program main
    use util, only: dp, eval
    implicit none
    character(200) str
    real(dp) ans

    str = "sqrt( 2.0 ) + 1000.0"
    call eval( str, ans )
    print *, "ans = ", ans

    str = "acos( x ) + 2000.0"
    call eval( str, ans, x= -1.0_dp )
    print *, "ans = ", ans

    str = "10 * x + y"
    call eval( str, ans, x= 1.0_dp, y= 2.0_dp )
    print *, "ans = ", ans
end program
结果:

$ gfortran test.f90    # gfortran >=5 is recommended
$ ./a.out
 ans =    1001.4142135623731
 ans =    2003.1415926535899
 ans =    12.000000000000000

更具体地说,上面的代码只是通过system()调用Python中的内置eval()函数。但这不是很有效,因为结果值一旦写入外部文件(以及调用Python本身的开销)。因此,如果效率很重要,那么最好使用更具体的第三方库,或者为了方便起见,直接使用解释语言。(如果计算要求不太高,我建议采用后一种方法,因为这样可以节省大量的编码时间……)

Python:

from __future__ import print_function, division
from math import *
str = input( "Input an expression: " )
x = 1.0
y = 2.0
print( eval( str ) )   # if you type "x + 10 * y" in the prompt, you get 21
朱莉娅:

println( "Input an expression: " )
str = readline()
x = 1.0
y = 2.0
println( eval( parse( str ) ) )

[编辑]

如果可以使用
system()
并编写外部文件,另一个选项可能是只编写一个包含要计算的表达式的小型Fortran代码,通过system()编译并运行它,通过外部文件获得结果。例如,如果我们将上述代码中的两行(
write(cmd),(a)…
system(trim(cmd))
)替换为以下内容,则会得到相同的结果。如果我们想让代码完全用Fortran编写,只需很少的修改,这可能很有用

    open( newunit=u, file="tmp.f90" )
    write( u, "(a)" ) "implicit none"
    write( u, "(a)" ) "real :: x, y"
    write( u, "(a)" ) trim(sx)
    write( u, "(a)" ) trim(sy)
    write( u, "(a)" ) "write(*,'(e30.20)') " // trim(expr)
    write( u, "(a)" ) "end"
    close( u )

    call system( "gfortran -fdefault-real-8 -ffree-line-length-none tmp.f90 && ./a.out > tmp.dat" )
         ! Assuming bash on Linux or Mac (x86_64).
         ! -fdefault-real-8 is attached to promote 1.0 etc to 8-byte floating-point values.

    call system( "rm -f tmp.f90" )

对于记录,该库允许您精确地执行您要求的操作:在Fortran中作为数学表达式计算字符串,而不需要任何其他编程语言。

对于记录,该库允许您精确地执行您要求的操作:在Fortran中作为数学表达式计算字符串,不需要任何其他编程语言。

几天前有类似的问题。我会做出同样的评论,为什么是fortran?解释语言(例如python)可以很容易地做这些事情。@agentp因为它是更复杂程序的开始部分。也许你是对的,我可以从Fortran内部调用像Octave、python等。。。。我将在几天前考虑类似的问题。我会做出同样的评论,为什么是fortran?解释语言(例如python)可以很容易地做这些事情。@agentp因为它是更复杂程序的开始部分。也许你是对的,我可以从Fortran内部调用像Octave、python等。。。。我将把行中的itRead看作一个ascii字符串,然后自己解析它。您将需要解析()/-+***和=。还有DSIN、SQRT等。使用反向波兰符号(RPN)可能是最简单的方法。@Holmz:正如我在回答中提到的,这样的解析器已经以。的形式存在。将行作为ascii字符串读入,然后自己解析。您将需要解析()/-+***和=。还有DSIN、SQRT等。使用反向波兰符号(RPN)可能是最简单的方法。@Holmz:正如我在回答中提到的,这样的解析器已经存在了