www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - string to real conversion losing data

reply jicman <cabrera_ _wrc.xerox.com> writes:
Greetings and salutations!

Will someone be so kind as to explain why this is happening?

----
import std.stdio;
import std.conv;

void main()
{
  char[][] strRealVals =
  [
    "14539.34","1230.00","361.62","1613.10","","","0.00"
  ];
  real rTotal = 0;
  foreach (char[] s; strRealVals)
  {
    writefln("Real value is: " ~ s);
    real r = 0.00;
    if (s != "")
      r = std.conv.toReal(s);
    rTotal += r;
  }
  writefln(std.string.toString(rTotal));
  writefln(rTotal);
}
----

When I run this program, I get this:
16:51:35.54>realtest
Real value is: 14539.34
Real value is: 1230.00
Real value is: 361.62
Real value is: 1613.10
Real value is:
Real value is:
Real value is: 0.00
17744.1
17744.1

----

If I add these numbers, the outcome should be 17744.06.  Any ideas?  I am using
Digital Mars D Compiler v1.046.

thanks,

josÚ
Apr 08 2010
next sibling parent reply wrzosk <dprogr gmail.com> writes:
W dniu 08.04.2010 23:02, jicman pisze:
 Greetings and salutations!

 Will someone be so kind as to explain why this is happening?

 ----
 import std.stdio;
 import std.conv;

 void main()
 {
    char[][] strRealVals =
    [
      "14539.34","1230.00","361.62","1613.10","","","0.00"
    ];
    real rTotal = 0;
    foreach (char[] s; strRealVals)
    {
      writefln("Real value is: " ~ s);
      real r = 0.00;
      if (s != "")
        r = std.conv.toReal(s);
      rTotal += r;
    }
    writefln(std.string.toString(rTotal));
    writefln(rTotal);
 }
 ----

 When I run this program, I get this:
 16:51:35.54>realtest
 Real value is: 14539.34
 Real value is: 1230.00
 Real value is: 361.62
 Real value is: 1613.10
 Real value is:
 Real value is:
 Real value is: 0.00
 17744.1
 17744.1

 ----

 If I add these numbers, the outcome should be 17744.06.  Any ideas?  I am
using Digital Mars D Compiler v1.046.

 thanks,

 jos´┐Ż

it is looking ok to me, try this one and thing why it is like that :) import std.stdio; import std.conv; void main() { writefln(17744.06); }
Apr 08 2010
parent jicman <cabrera_ _wrc.xerox.com> writes:
wrzosk Wrote:

 W dniu 08.04.2010 23:02, jicman pisze:

it is looking ok to me, try this one and thing why it is like that :) import std.stdio; import std.conv; void main() { writefln(17744.06); }

Ok, I'll bite... I don't get it. does that mean that writefln is buggy? How can I format and write this to a file? Is there a formatting library? thanks, jose
Apr 08 2010
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
 If I add these numbers, the outcome should be 17744.06.  Any ideas?  I am
using Digital Mars D Compiler v1.046.
 josÚ

This prints the same values, using latest D2: import std.stdio, std.conv; void main() { real tot = 0; foreach(el; ["14539.34","1230.00","361.62","1613.10","0.00"]) tot += to!real(el); writefln("%.5f\n", tot); // 17744.06000 tot = 0; foreach(el; [14539.34,1230.00,361.62,1613.10,0.00]) tot += to!real(el); writefln("%.5f\n", tot); // 17744.06000 } Bye, bearophile
Apr 08 2010
parent BCS <none anon.com> writes:
Hello bearophile,

 writefln("%.5f\n", tot); // 17744.06000

Never trust your output function :) (e.i. always check to see if it's doing what you think it is.) Back in the bad old days, a guy I knew spent a while debugging a problem that turned out to be that he was loading data as float but storing it into an int (think an invalid scanf format string). Every time he checked things though things seems OK because he had the same bug in his output as well (think printf). -- ... <IXOYE><
Apr 08 2010
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
jicman wrote:
 Greetings and salutations!
 
 Will someone be so kind as to explain why this is happening?
 
 ----
 import std.stdio;
 import std.conv;
 
 void main()
 {
   char[][] strRealVals =
   [
     "14539.34","1230.00","361.62","1613.10","","","0.00"
   ];
   real rTotal = 0;
   foreach (char[] s; strRealVals)
   {
     writefln("Real value is: " ~ s);
     real r = 0.00;
     if (s != "")
       r = std.conv.toReal(s);
     rTotal += r;
   }
   writefln(std.string.toString(rTotal));
   writefln(rTotal);
 }
 ----
 
 When I run this program, I get this:
 16:51:35.54>realtest
 Real value is: 14539.34
 Real value is: 1230.00
 Real value is: 361.62
 Real value is: 1613.10
 Real value is:
 Real value is:
 Real value is: 0.00
 17744.1
 17744.1
 
 ----
 
 If I add these numbers, the outcome should be 17744.06.  Any ideas?  I am
using Digital Mars D Compiler v1.046.
 
 thanks,
 
 jos´┐Ż
 

The default format string for floating point values is 6 decimal digits of precision (the digits before and after the decimal point). writefln is rounding the value up. Try for example "%.18f" for 'real'. This does it automatically: import std.stdio; import std.string; void main() { auto theValue = 17744.06L; writefln("%s has %s decimal digits of precision", typeof(theValue).stringof, theValue.dig); auto formatString = format("%%.%sf", theValue.dig); writefln(formatString, theValue); } Ali
Apr 08 2010
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
Ali Çehreli wrote:

 Try for example "%.18f" for 'real'.

Well... That will be too many digits unless the number of digits before the decimal point is zero. The decimal digits before and after the point should be 18 for most accurate representation. But the OP probably doesn't need that many digits anyway. Here are more options: http://digitalmars.com/d/2.0/phobos/std_format.html Ali
Apr 08 2010
prev sibling parent jicman <cabrera_ _wrc.xerox.com> writes:
Ali Çehreli Wrote:

 jicman wrote:
 Greetings and salutations!
 
 Will someone be so kind as to explain why this is happening?
 
 ----
 import std.stdio;
 import std.conv;
 
 void main()
 {
   char[][] strRealVals =
   [
     "14539.34","1230.00","361.62","1613.10","","","0.00"
   ];
   real rTotal = 0;
   foreach (char[] s; strRealVals)
   {
     writefln("Real value is: " ~ s);
     real r = 0.00;
     if (s != "")
       r = std.conv.toReal(s);
     rTotal += r;
   }
   writefln(std.string.toString(rTotal));
   writefln(rTotal);
 }
 ----
 
 When I run this program, I get this:
 16:51:35.54>realtest
 Real value is: 14539.34
 Real value is: 1230.00
 Real value is: 361.62
 Real value is: 1613.10
 Real value is:
 Real value is:
 Real value is: 0.00
 17744.1
 17744.1
 
 ----
 
 If I add these numbers, the outcome should be 17744.06.  Any ideas?  I am
using Digital Mars D Compiler v1.046.
 
 thanks,
 
 jos´┐Ż
 

The default format string for floating point values is 6 decimal digits of precision (the digits before and after the decimal point). writefln is rounding the value up. Try for example "%.18f" for 'real'. This does it automatically: import std.stdio; import std.string; void main() { auto theValue = 17744.06L; writefln("%s has %s decimal digits of precision", typeof(theValue).stringof, theValue.dig); auto formatString = format("%%.%sf", theValue.dig); writefln(formatString, theValue); }

thanks. That worked. jic
Apr 09 2010