Reputation: 7395
Using writef()
, I can control the output precision of a floating-point number, for example:
writef( "%20.15dr\n", 1.0 / 3.0 ); // 0.333333333333333
but if I use writeln()
for convenience, the number is output with 6 digits:
writeln( 1.0 / 3.0 ); // 0.333333
Is there possibly a way to control the default output precision of floating-point numbers for writeln()
..? (e.g., via some environment variable?)
For comparison, some languages output 15 digits and some 6 digits by default, so the result seems to vary depending on languages (or compilers).
# 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
Upvotes: 5
Views: 127
Reputation: 4008
Yes there is. In Chapel, I/O is performed on channels. Each channel has an I/O style (represented by a record of type iostyle
) which specifies how values are printed to that channel if a more specific style is not provided within the read/write call itself. A call to writeln()
is essentially a call to stdout.writeln()
where stdout
is a channel whose output shows up in the console.
The following example shows how to change the I/O style of stdout (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 );
where the output is:
0.333333
0.333333333333333
0.333333
Note that it isn't safe to change the style of a channel in parallel code without locking it first. Since the example above is completely serial, it's OK, but in the context of a larger, potentially parallel, program, the better approach would be to lock the channel before setting its style, as follows (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 );
Chapel's online documentation has more information about I/O styles, the fields of the iostyle
record, and locking of channels.
Upvotes: 5
Reputation: 431
Use iostyle and _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
You can also pass other things to new iostyle()
, for example:
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
Upvotes: 5