浮点数的writeln()输出精度

时间:2019-01-23 16:51:05

标签: chapel

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

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

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

writeln( 1.0 / 3.0 );                   // 0.333333

是否有一种方法可以控制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

2 个答案:

答案 0 :(得分: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

您还可以将其他内容传递给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

答案 1 :(得分:5)

是的。在Chapel中,I / O在通道上执行。每个通道都有一个I / O样式(由类型为... + geom_text(aes(y = 1 - lab.y.mid, label = ind), alpha = 1) 的记录表示),它指定如果在读/写调用自身中未提供更特定的样式时,如何将值打印到该通道。对iostyle的调用实质上是对writeln()的调用,其中stdout.writeln()是其输出显示在控制台中的通道。

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

stdout

其中的输出是:

// 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 );

请注意,在不先锁定通道的情况下更改并行代码的通道样式是不安全的。由于上面的示例完全是串行的,所以可以,但是在较大的,可能是并行程序的情况下,更好的方法是在设置其样式之前锁定通道,如下所示(Try it Online):

0.333333
0.333333333333333
0.333333

Chapel的在线文档包含有关I/O stylesiostyle recordlocking of channels字段的更多信息。