当我尝试使用gfortran编译calrank.for(CALRANK_v7.0.0_L140912.zip)时,出现此错误:
> gfortran -m64 -c -o calrank.o calrank.for
calrank.for:1922:32:
write(io,'(2f10.3,1p1000(2x,e16.7,1x,2a10,1x))')
1
Error: Comma required after P descriptor in format string at (1)
当我做逗号时,我遇到了同样的错误。
我只注意到该代码是在LF95之前编译的。
subroutine xycout(io,nrank,nsp)
use userinf
use header
use rankdata
implicit none
integer :: io,nrank,nsp
integer :: k,ir,is,i
character(len=20) :: head1,head2,head3
character(len=40) :: add1x,add2x,add3x
character(len=40) :: add1(nsp),add2(nsp)
character(len=40) :: add3(nsp)
......
c --- Loop over receptors to write data records
do ir=1,ntotrec(k)
write(io,'(2f10.3,1p1000(2x,e16.7,1x,2a10,1x))')
& xreckm(ir,k),yreckm(ir,k),
& (xounit(is,k)*rankvalue(ir,is,nrank),
& arankdate(ir,is,nrank),
& aranktime(ir,is,nrank),is=1,nspout(k))
enddo
return
end
一些变量在代码的其他位置定义为:
c --- Real arrays for header (derived)
allocate (xreckm(mxrec,k),yreckm(mxrec,k))
c --- Modified units multiplier
allocate (xounit(mxspout,k))
c --- Array of values (all species, receptors) for requested ranks
allocate (rankvalue(ntotrec(k),nspout(k),n_ranks))
allocate (arankdate(ntotrec(k),nspout(k),n_ranks))
allocate (aranktime(ntotrec(k),nspout(k),n_ranks))
c --- Integer arrays for header
deallocate (ndrec,nctrec,nspout,i2dmet,iutmzn)
答案 0 :(得分:2)
您应该完全按照错误消息的说明进行操作,在p描述符后面加上逗号:
write(io,'(2f10.3,1p,1000(2x,e16.7,1x,2a10,1x))')
如果您不知道什么是p描述符,请参见https://docs.oracle.com/cd/E19957-01/805-4939/z4000743a6e2/index.html或有关Fortran编辑描述符的任何教程。正如史蒂芬·莱昂内尔(Steven Lionel)在下面的评论所述,您可以在普通数据编辑描述符之前使用p描述符,而无需使用逗号。
答案 1 :(得分:2)
@francescalus建议我扩大评论范围。
首先,Fortran通常需要在两个“格式项”之间使用逗号。格式项是带有或不带重复计数的编辑描述符(F,E等),或者是带括号的格式项组(可能有自己的重复计数;提到了@Vladimir F *-这是“无限重复计数”,并且只能与带括号的组一起使用。
逗号可以省略:
现在,对于P编辑描述符,这将设置比例因子,这确实很奇怪,并且根据您执行的编辑类型的不同,其效果也大不相同。它也是“粘性”的,并适用于该格式的所有后续编辑。
在输入时,它将导致读取值除以10 ** k,其中k是比例因子(2P表示k = 2,依此类推)。因此,如果输入的字符为123且2P有效,则该值读取为1.23。同样,如果-2P有效,则123表示为12300。输入中的小数点不会更改此值,但是指数会删除缩放比例。因此,以2P读取的1.23是.0123,而1.23E0是1.23。
在使用F编辑的输出上,它会使输出值乘以10 ** k,从而反转输入方案。
您可能会问为什么?答案在于打孔卡,打孔卡是1950年代至70年代使用的一种输入(有时是输出)形式。它们有80列,而在小数点上浪费一列可能是一个问题。因此比例因子允许人们省略小数点,但仍然得到分数。
但是等等,它变得陌生了!在使用E和D编辑的输出中,比例因子仅确定小数点左侧的前导位数(以及随后的指数减少。因此,对于1.23的值和2P,E11.3的格式,您会得到b12.300E-01(除非SP生效,否则b =空白,这是第二天的答复。)
对于G格式的输出?甚至更奇怪。如果该值在获得与F格式等效的范围内,则比例因子无效,否则其行为类似于E。
最后,比例因子对EN,ES或EX编辑没有影响。 (例如,这是F2018的十六进制浮点输出功能。)
P格式的一个好用法是在使用整数而不是实数进行货币计算时,因为后者可能会失去精度(例如.01,没有精确的二进制浮点表示形式。)假设您要处理的值是aren不会太大,您可以将美元和美分读为-2P格式的整数,而不会因加,减和乘而损失任何便士。我曾经以这种精确的方式编写抵押计算器。