代码之家  ›  专栏  ›  技术社区  ›  roygvib

浮点数的“writeln()”的输出精度

  •  5
  • roygvib  · 技术社区  · 6 年前

    使用 writef() ,我可以控制浮点数的输出精度,例如:

    writef( "%20.15dr\n", 1.0 / 3.0 );      // 0.333333333333333
    

    但是如果我使用 writeln() 为方便起见,数字输出为6位数字:

    writeln( 1.0 / 3.0 );                   // 0.333333
    

    是否可能有方法控制浮点数的默认输出精度 写入() …?(例如,通过一些环境变量?)

    为了进行比较,一些语言默认输出15位数字和6位数字,因此结果似乎因语言(或编译器)而异。

    # python2
    print 1.0 / 3.0      # 0.333333333333
    # python3
    print( 1.0 / 3.0 )   # 0.3333333333333333
    # julia
    println( 1.0 / 3.0 )   # 0.3333333333333333
    # gfortran
    print *, 1.0d0 / 3.0d0   # 0.33333333333333331
    # swift
    print( 1.0 / 3.0 )       # 0.333333333333333
    # nim
    echo( 1.0 / 3.0 )       # 0.3333333333333333
    # g++
    cout << 1.0 / 3.0 << endl;   # 0.333333
    # d (dmd)
    writeln( 1.0 / 3.0 );      # 0.333333
    
    2 回复  |  直到 6 年前
        1
  •  5
  •   Vass    6 年前

    使用 iostyle _set_style() :

    writeln(100.0/3.0);   // 33.3333
    
    stdout.lock();
    stdout._set_style(new iostyle(precision=10));
    stdout.unlock();
    
    writeln(100.0/3.0);   // 33.33333333
    

    你也可以把其他东西传给 new iostyle() 例如:

    precision=10, realfmt=0          // like %.10g in C:  33.33333333      (default)
    precision=10, realfmt=1          // like %.10f in C:  33.3333333333
    precision=10, realfmt=2          // like %.10e in C:  3.3333333333e+01
    
        2
  •  5
  •   Brad    6 年前

    是的。在教堂中,I/O在 渠道 . 每个通道都有一个I/O样式(由类型的记录表示 iostyle )它指定在读/写调用本身没有提供更具体的样式时如何将值打印到该通道。对…的呼唤 writeln() 本质上是对 stdout.writeln() 哪里 stdout 是一个输出显示在控制台中的通道。

    以下示例显示如何更改stdout的I/O样式( Try it Online ):

    // print to stdout using its default style                                                
    writeln( 1.0 / 3.0 );
    
    // create a new IO style with a precision of 15                                   
    var style = new iostyle(precision=15);
    
    // change stdout to use this new style                                          
    stdout._set_style(style);
    
    // print using the new style                                                    
    writeln( 1.0 / 3.0 );
    
    // restore the default style and print once more                                
    stdout._set_style(defaultIOStyle());
    writeln( 1.0 / 3.0 );
    

    其中输出为:

    0.333333
    0.333333333333333
    0.333333
    

    注意,在并行代码中更改通道样式而不首先锁定它是不安全的。由于上面的例子是完全串行的,所以没关系,但是在一个更大的、可能是并行的程序环境中,更好的方法是在设置其样式之前锁定通道,如下所示( Try it Online ):

    // print to stdout using its default style                                                
    writeln( 1.0 / 3.0 );
    
    // create a new IO style with a precision of 15                                   
    var style = new iostyle(precision=15);
    
    // change stdout to use this new style                                          
    stdout.lock();
    stdout._set_style(style);
    stdout.unlock();
    
    // print using the new style                                                    
    writeln( 1.0 / 3.0 );
    
    // restore the default style and print once more                                
    stdout.lock();
    stdout._set_style(defaultIOStyle());
    stdout.unlock();
    writeln( 1.0 / 3.0 );
    

    查普尔的在线文档有更多关于 I/O styles ,的字段 iostyle record locking of channels .