Skip to content

Commit

Permalink
Merge pull request #3870 from panzone/correct-real-write
Browse files Browse the repository at this point in the history
Correct real write bug

[Patch prepared by @Panzone and reviewed/merged by @mppf]

This pull request tries to correct the bug noticed in #2148. It will switch to an exponential notation if the standard precision isn't enough to print the decimal part of the number.

Passed test/io and test/release on both linux64 and darwin with default settings.
[And passed full local testing]
  • Loading branch information
mppf committed May 18, 2016
2 parents 3b194ba + 8a42be5 commit 96428e1
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 30 deletions.
49 changes: 47 additions & 2 deletions runtime/src/qio/qio_formatted.c
Original file line number Diff line number Diff line change
Expand Up @@ -2589,6 +2589,28 @@ int _ltoa(char* restrict dst, size_t size, uint64_t num, int isnegative,
return i;
}

//This function finds where the last non-zero digit
//is in the decimal part of an exponential number.
//
//This will be used in _ftoa_core for resolve a
//a problem about trailing zeroes.
static int _find_prec(char *buf, int len){
int dp_index = 0;
int last_dig = 0;
int index = 0;

//Find where the decimal point is
while( dp_index < len && buf[dp_index++] != '.');

//Explore the decimal part for find where the
//last non-zero digit is.
for( index = dp_index; index < len && buf[index] != 'e'; index++ ){
if( buf[index] != '0' )
last_dig = index - dp_index + 1;
}
return last_dig;
}

// Converts num to a string in buf, returns the number
// of bytes that would be used if space permits (not including null)
// or -1 on error
Expand Down Expand Up @@ -2656,9 +2678,32 @@ int _ftoa_core(char* buf, size_t buf_sz, double num,
} else if( realfmt == 0 ) {
if( precision < 0 ) {
if( uppercase ) {
got = snprintf(buf, buf_sz, "%G", num);
// This if is necessary because if the number has
// 6 digits in the integer part, %g will not print
// the decimal part because the integer part have
// a number of digits equals to the standard precision.
if(num >= 100000.0 && num < 1000000.0){
got = snprintf(buf, buf_sz, "%.5E", num);
//Since we force the %.5e for maintain a precision of
//6 digits, the output could include some trailing zeroes.
//With _find_prec, we find how much digits we need.
//
//It can also be done starting from the number itself
//but this way avoids to deal with the loss of precision
//caused by floating point representation
if(buf_sz > 0)
got = snprintf(buf, buf_sz, "%.*E",_find_prec(buf, got), num);
}
else
got = snprintf(buf, buf_sz, "%G", num);
} else {
got = snprintf(buf, buf_sz, "%g", num);
if(num >= 100000.0 && num < 1000000.0){
got = snprintf(buf, buf_sz, "%.5e", num);
if(buf_sz > 0)
got = snprintf(buf, buf_sz, "%.*e",_find_prec(buf, got), num);
}
else
got = snprintf(buf, buf_sz, "%g", num);
}
} else {
if( uppercase ) {
Expand Down
23 changes: 23 additions & 0 deletions test/io/panzone/real-writeln.chpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var a: real = 1.0;
writeln("a = ", a);

var b: real = 10.0;
writeln("b = ", b);

var c: real = 100.0;
writeln("c = ", c);

var d: real = 1000.0;
writeln("d = ", d);

var e: real = 10000.0;
writeln("e = ", e);

var f: real = 100000.0;
writeln("f = ", f);

var g: real = 1000000.0;
writeln("g = ", g);

var h: real = 100000.9;
writeln("h = ", h);
8 changes: 8 additions & 0 deletions test/io/panzone/real-writeln.good
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
a = 1.0
b = 10.0
c = 100.0
d = 1000.0
e = 10000.0
f = 1e+05
g = 1e+06
h = 1.00001e+05
2 changes: 1 addition & 1 deletion test/modules/standard/math/acosh.good
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ b = 1.5
acosh(b) = 0.962424
c = 2.0
acosh(c) = 1.31696
d = 100000.0
d = 1e+05
acosh(d) = 12.2061
e = 1e+09
acosh(e) = 21.4164
51 changes: 28 additions & 23 deletions test/modules/standard/memory/countMemory/countMemory.makegood
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,38 @@ $realMemInKBytesVal = $realMemInBytesVal / 1024;
$realMemInMBytesVal = $realMemInKBytesVal / 1024;
$realMemInGBytesVal = $realMemInMBytesVal / 1024;

$realMemInBytes = sprintf("%g", $realMemInBytesVal);
$realMemInKBytes = sprintf("%g", $realMemInKBytesVal);
$realMemInMBytes = sprintf("%g", $realMemInMBytesVal);
$realMemInGBytes = sprintf("%g", $realMemInGBytesVal);
$realMemInBytes = print_chapel_real($realMemInBytesVal);
$realMemInKBytes = print_chapel_real($realMemInKBytesVal);
$realMemInMBytes = print_chapel_real($realMemInMBytesVal);
$realMemInGBytes = print_chapel_real($realMemInGBytesVal);


#
# if a string is all digits, add a trailing .0 to match
# Chapel's default formatting of reals
#
if ($realMemInBytes =~ m/^\d+$/) {
$realMemInBytes .= ".0";
}
if ($realMemInKBytes =~ m/^\d+$/) {
$realMemInKBytes .= ".0";
}
if ($realMemInMBytes =~ m/^\d+$/) {
$realMemInMBytes .= ".0";
}
if ($realMemInGBytes =~ m/^\d+$/) {
$realMemInGBytes .= ".0";
}


printf "memory is: %s\n", $realMemInBytes;
printf " in bytes: %s\n", $realMemInBytes;
printf " in kb: %s\n", $realMemInKBytes;
printf " in mb: %s\n", $realMemInMBytes;
printf " in gb: %s\n", $realMemInGBytes;

#
# This is for change the formatting of a float number
# to the Chapel's formatting of reals
#
sub print_chapel_real{
$retVal = 0;
if( ($_[0] >= 100000.0) and ($_[0] < 1000000.0) ){
$retVal = sprintf("%.5e", $_[0]);
$retVal =~ s/0+e/e/; #for removing the zeroes
}
else {
$retVal = sprintf("%g", $_[0]);
}

#
# if a string is all digits, add a trailing .0 to match
# Chapel's default formatting of reals
#
if ($retVal =~ m/^\d+$/) {
$retVal .= ".0";
}

return $retVal;
}
2 changes: 1 addition & 1 deletion test/types/scalar/bradc/piVals.good
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
x is: 3.14159e+08
x is: 159265.0
x is: 1.59265e+05
2 changes: 1 addition & 1 deletion test/types/scalar/bradc/piVals1a.good
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
x is: 3.14159e+08
y is: 3.14159e+08
x is: 159265.0
x is: 1.59265e+05
2 changes: 1 addition & 1 deletion test/types/scalar/bradc/piVals2.good
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
x is: 3.14159e+08
x is: 159265.0
x is: 1.59265e+05
2 changes: 1 addition & 1 deletion test/users/shetag/tensor.good
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ m4.setitem(2,2,100) = {n = 3, m = 6, a = 2.0 3.0 4.0 5.0 6.0 7.0
3.0 100.0 5.0 6.0 7.0 8.0
4.0 5.0 6.0 7.0 8.0 9.0}
m4.mul(v3) = {n = 3, a = 270.0 1290.0 390.0}
m4.rmul(v4) = {n = 6, a = 28200.0 337080.0 46920.0 56280.0 65640.0 75000.0}
m4.rmul(v4) = {n = 6, a = 28200.0 3.3708e+05 46920.0 56280.0 65640.0 75000.0}

0 comments on commit 96428e1

Please sign in to comment.