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
The precision of floating-point numbers is either single or double, based on the number of hexadecimal digits in the fraction. A small integer is a binary integer with a precision of 15 bits. The range of small integers is -32768 to +32767. A large integer is a binary integer with a precision of 31 bits.
Precision: The smallest change that can be represented in floating point representation is called as precision. The fractional part of a single precision normalized number has exactly 23 bits of resolution, (24 bits with the implied bit).
FLOAT data types usually require 8 bytes of storage per value. Conversion of a FLOAT value to a DECIMAL value results in 17 digits of precision.
The data type float has 24 bits of precision. This is equivalent to only about 7 decimal places. (The rest of the 32 bits are used for the sign and size of the number.) The number of places of precision for float is the same no matter what the size of the number.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With