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
Fortran-要四舍五入到一个小数点吗_Fortran_Rounding_Gfortran_Netcdf - Fatal编程技术网

Fortran-要四舍五入到一个小数点吗

Fortran-要四舍五入到一个小数点吗,fortran,rounding,gfortran,netcdf,Fortran,Rounding,Gfortran,Netcdf,在fortran语言中,我必须将纬度和经度四舍五入到小数点后一位 我正在使用gfortran编译器和nint函数,但以下功能不起作用: print *, nint( 1.40 * 10. ) / 10. ! prints 1.39999998 print *, nint( 1.49 * 10. ) / 10. ! prints 1.50000000 在这里寻找通用和特定的解决方案。例如: print '(5(1x, f0.1))', 1.30, 1.31, 1.35, 1.39,

在fortran语言中,我必须将纬度和经度四舍五入到小数点后一位

我正在使用gfortran编译器和nint函数,但以下功能不起作用:

print *, nint( 1.40 * 10. ) / 10.    ! prints 1.39999998
print *, nint( 1.49 * 10. ) / 10.    ! prints 1.50000000
在这里寻找通用和特定的解决方案。例如:

print '(5(1x, f0.1))', 1.30, 1.31, 1.35, 1.39, 345.46
  • 我们如何显示四舍五入到小数点后一位的数字

  • 我们如何在fortran中存储这样的整数。这在浮点变量中是不可能的,但是还有其他方法吗

  • 我们如何将这些数字写入NetCDF

  • 我们如何将这些数字写入CSV或文本文件


  • 没有办法按你的要求去做。潜在的问题是,您想要的舍入值不一定能够用浮点表示

    例如,如果值为10.58,则在IEEE754 float32中精确表示为1.3225000 x 2^3=10.580000

    当您将该值四舍五入到一个小数点时(无论您如何选择),结果将是10.6,但是10.6没有精确的表示形式。最接近的表示形式为1.3249999x2^3=10.599999(以浮点32表示)。因此,无论您如何处理舍入,都无法将10.6精确存储在float32值中,也无法将其作为浮点值写入netCDF文件。

    是的,可以做到!上面的“已接受”答案在其有限的范围内是正确的,但在Fortran(或其他各种HGL)中实际可以实现的方面是错误的

    唯一的问题是,如果像写F(6.1)这样的东西失败了,你愿意付出什么代价

    从一个角度来看,您的问题是“任意精度”计算主题的一个特别微小的变化。当您需要以精确的精度存储、操作和执行1024位数字的“数学”运算时,您认为加密是如何处理的

    在这种情况下,一个简单的策略是将每个数字分成其组成部分“LHSofD”(十进制的左侧)和“RHSofD”值。例如,您可能有一个RLon(i,j)=105.591,并且希望将105.6(或任何舍入方式)打印到您的netCDF(或任何普通)文件中。将其拆分为RLonLHS(i,j)=105和RLonRHS(i,j)=591

    。。。在这一点上,您可以选择增加通用性,但要付出一些代价。为了节省“钱”,RHS可能会保留为0.591(但如果需要做更高级的事情,则可放宽通用性)

    为了简单起见,假设第二种策略是“便宜而快乐”

    LHS很简单(Int())

    现在,对于RHS,乘以10(如果您希望四舍五入到1 DEC),例如得出RLonRHS(i,j)=5.91,然后应用Fortran“四舍五入到最接近的整数”NInt()。。。留给你的是RLonRHS(i,j)=6.0

    。。。鲍勃是你叔叔:

    现在,您可以使用连接“Dual”的合适写入语句将LHS和RHS打印到netCDF中,并将根据OP中要求的目标创建精确的表示

    。。。当然,以后读入这些值会返回到与上面所示相同的问题,除非读入也是ArbPrec感知的


    。。。我们编写了自己的ArbPrec库,但在VBA和其他HGL中也有一些关于。。。但是请注意,一个完整的机器是一件非常重要的事情。。。幸运的是,问题很简单。

    正如其他人所说,问题在于NetCDF文件中使用浮点表示。使用
    nco
    实用程序,可以将纬度/经度更改为带有比例因子的短整数,并添加偏移量。像这样:

    ncap2 -s 'latitude=pack(latitude, 0.1, 0); longitude=pack(longitude, 0.1, 0);' old.nc new.nc
    
    “round_x=nint(x*10d0)/10d0”运算符将x取整(对于abs(x)<2**31/10,对于较大的数字,使用dnint()),并将取整后的值分配给round_x变量以供进一步计算

    如上所述,并非所有小数点后有一个有效数字的数字都有精确的表示形式,例如,0.3没有

    print *, 0.3d0
    
    输出:

      0.29999999999999999
    
     1.3 1.3 1.4 1.4 345.5
    
    要将舍入值输出到文件、屏幕或将其转换为小数点后有一个有效数字的字符串,请使用编辑描述符“Fw.1”(w-宽度w字符,0-可变宽度)。例如:

    print '(5(1x, f0.1))', 1.30, 1.31, 1.35, 1.39, 345.46
    
    输出:

      0.29999999999999999
    
     1.3 1.3 1.4 1.4 345.5
    
    @JohnE,使用“G10.2”是不正确的,它将结果舍入到两个有效数字,而不是小数点后的一个数字。例如:

    print '(g10.2)',  345.46
    
    输出:

      0.29999999999999999
    
     1.3 1.3 1.4 1.4 345.5
    
    0.35E+03

    附言

    对于NetCDF,取整应由NetCDF查看器处理,但是,您可以将变量输出为NC_字符串类型:

    write(NetCDF_out_string, '(F0.1)') 1.49
    
    或者,获得“漂亮”NC\U浮点/NC\U双倍数字:

    beautiful_float_x = nint(x*10.)/10. + epsilon(1.)*nint(x*10.)/10./2.
    beautiful_double_x = dnint(x*10d0)/10d0 + epsilon(1d0)*dnint(x*10d0)/10d0/2d0
    
    p.p.S.@JohnE

  • 首选的解决方案不是在内存或文件中舍入中间结果。仅当发出人类可读数据的最终输出时才执行舍入

  • 使用带有编辑描述符“Fw.1”的打印,见上文

  • 没有简单可靠的方法精确存储舍入数(小数点固定的数字):

  • 2.1。理论上,一些Fortran实现可以支持十进制算法,但我不知道“selected_real_kind(4,4,10)”返回的值不是-5

    2.2。可以将舍入的数字存储为字符串

    2.3。您可以使用GIMP库的Fortran绑定。带有mpq_uu前缀的函数设计用于有理数

  • 没有简单可靠的方法可以在netCDF文件中写入四舍五入的数字,同时为该文件的读取器保留其属性:
  • 3.1。netCDF支持“压缩数据值”,即您可以使用“比例因子”、“添加偏移量”和保存整数数组等属性设置整数类型。但是,在文件中,“比例因子”将存储为单精度或双精度的浮点数,即该值将不同于0.1。因此,在读取时,通过netCDF库计算时
    unpacketed_data_value=packeted_data_value*scale_factor+add_of