用于浮点数的`writeln()`的输出精度

roy*_*vib 5 chapel

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

writef( "%20.15dr\n", 1.0 / 3.0 );      // 0.333333333333333
Run Code Online (Sandbox Code Playgroud)

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

writeln( 1.0 / 3.0 );                   // 0.333333
Run Code Online (Sandbox Code Playgroud)

是否有可能控制浮点数的默认输出精度为writeln()...?(例如,通过一些环境变量?)

为了比较,默认情况下,某些语言输出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
Run Code Online (Sandbox Code Playgroud)

Vas*_*ass 5

使用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
Run Code Online (Sandbox Code Playgroud)

您还可以传递其他内容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
Run Code Online (Sandbox Code Playgroud)


Bra*_*rad 5

就在这里.在Chapel中,I/O在通道上执行.每个通道都有一个I/O样式(由类型记录表示iostyle),它指定如果在读/写调用本身内没有提供更具体的样式,如何将值打印到该通道.呼叫writeln()本质stdout.writeln()stdout是对其输出显示在控制台中的通道的调用.

以下示例显示如何更改stdout的I/O样式(在线尝试):

// 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 );
Run Code Online (Sandbox Code Playgroud)

输出的位置是:

0.333333
0.333333333333333
0.333333
Run Code Online (Sandbox Code Playgroud)

请注意,在不首先锁定并行代码的情况下更改并行代码中的通道样式是不安全的.由于上面的示例是完全串行的,所以没关系,但是在更大的,可能并行的程序的上下文中,更好的方法是在设置其样式之前锁定通道,如下所示(在线试试):

// 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 );
Run Code Online (Sandbox Code Playgroud)

Chapel的在线文档提供了有关I/O样式,iostyle记录字段和通道锁定的更多信息.

  • 我相信这应该是安全的.除非我弄错了,否则只有在其他任务同时使用通道时更改样式时才需要锁定. (3认同)
  • 非常感谢更多的例子!我有一个问题...对于一个小的测试代码(只有一个文件),通常可以放"stdout._set_style(new iostyle(precision = 10));" 在该源文件的顶部,即使它在代码中执行"forall",没有stdout.lock/unlock?(即,在并行执行期间,我不会更改此类IO样式.) (2认同)