www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Floating point to string

reply Joe <Joe_member pathlink.com> writes:
How to do get a full string representation of a floating point?

I've tried toString() on a floating point and the default precision for 
numbers after the decimal point is 6.  I've also tried using format 
strings, but I can't seem to get a full textual representation of a 
floating point.  Is there some trick I'm missing?

-Joe
Jul 18 2007
parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Wed, 18 Jul 2007 21:28:47 -0500, Joe wrote:

 How to do get a full string representation of a floating point?
 
 I've tried toString() on a floating point and the default precision for 
 numbers after the decimal point is 6.  I've also tried using format 
 strings, but I can't seem to get a full textual representation of a 
 floating point.  Is there some trick I'm missing?
Try this ... <dcode> import std.stdio; import std.string; string FullTextValue(T)(T x) { string s; static if(is (T:long)) const fmt = "%-52d"; else static if(is (T:real)) const fmt = "%52.52f"; else const fmt = "%-s"; s = std.string.format( fmt, x); for (int i = s.length-1; i >= 0; i--) { if (s[i] == '.') { s.length = i+2; break; } if ((s[i] != '0' && s[i] != ' ') || (i == 0)) { s.length = i+1; break; } } return s; } void main() { real x; double y; float z; long a; x = 12345678901234567890.1234567890123456789; y = x; z = x; a = cast(typeof(a))x; writefln("real '%s'", FullTextValue(x)); writefln("double '%s'", FullTextValue(y)); writefln("float '%s'", FullTextValue(z)); writefln("long '%s'", FullTextValue(a)); x = 0.1234567890123456789; y = x; z = x; a = cast(typeof(a))x; writefln("real '%s'", FullTextValue(x)); writefln("double '%s'", FullTextValue(y)); writefln("float '%s'", FullTextValue(z)); writefln("long '%s'", FullTextValue(a)); } </dcode> -- Derek (skype: derek.j.parnell) Melbourne, Australia 19/07/2007 2:41:16 PM
Jul 18 2007
parent reply Joe <Joe_member pathlink.com> writes:
Derek Parnell wrote:
 On Wed, 18 Jul 2007 21:28:47 -0500, Joe wrote:
 
 How to do get a full string representation of a floating point?

 I've tried toString() on a floating point and the default precision for 
 numbers after the decimal point is 6.  I've also tried using format 
 strings, but I can't seem to get a full textual representation of a 
 floating point.  Is there some trick I'm missing?
Try this ... <dcode> import std.stdio; import std.string; string FullTextValue(T)(T x) { string s; static if(is (T:long)) const fmt = "%-52d"; else static if(is (T:real)) const fmt = "%52.52f"; else const fmt = "%-s"; s = std.string.format( fmt, x); for (int i = s.length-1; i >= 0; i--) { if (s[i] == '.') { s.length = i+2; break; } if ((s[i] != '0' && s[i] != ' ') || (i == 0)) { s.length = i+1; break; } } return s; } void main() { real x; double y; float z; long a; x = 12345678901234567890.1234567890123456789; y = x; z = x; a = cast(typeof(a))x; writefln("real '%s'", FullTextValue(x)); writefln("double '%s'", FullTextValue(y)); writefln("float '%s'", FullTextValue(z)); writefln("long '%s'", FullTextValue(a)); x = 0.1234567890123456789; y = x; z = x; a = cast(typeof(a))x; writefln("real '%s'", FullTextValue(x)); writefln("double '%s'", FullTextValue(y)); writefln("float '%s'", FullTextValue(z)); writefln("long '%s'", FullTextValue(a)); } </dcode>
Thanks. Out of curiosity (note: I haven't run this example yet), is 52 a magic number for the floating point types in D? Is there a way at runtime to get at the number of digits available after the decimal point depending on whether it's a float, double or real?
Jul 18 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Joe wrote:
 Derek Parnell wrote:
 On Wed, 18 Jul 2007 21:28:47 -0500, Joe wrote:

 How to do get a full string representation of a floating point?

 I've tried toString() on a floating point and the default precision 
 for numbers after the decimal point is 6.  I've also tried using 
 format strings, but I can't seem to get a full textual representation 
 of a floating point.  Is there some trick I'm missing?
Try this ... <dcode> import std.stdio; import std.string; string FullTextValue(T)(T x) { string s; static if(is (T:long)) const fmt = "%-52d"; else static if(is (T:real)) const fmt = "%52.52f"; else const fmt = "%-s"; s = std.string.format( fmt, x); for (int i = s.length-1; i >= 0; i--) { if (s[i] == '.') { s.length = i+2; break; } if ((s[i] != '0' && s[i] != ' ') || (i == 0)) { s.length = i+1; break; } } return s; } void main() { real x; double y; float z; long a; x = 12345678901234567890.1234567890123456789; y = x; z = x; a = cast(typeof(a))x; writefln("real '%s'", FullTextValue(x)); writefln("double '%s'", FullTextValue(y)); writefln("float '%s'", FullTextValue(z)); writefln("long '%s'", FullTextValue(a)); x = 0.1234567890123456789; y = x; z = x; a = cast(typeof(a))x; writefln("real '%s'", FullTextValue(x)); writefln("double '%s'", FullTextValue(y)); writefln("float '%s'", FullTextValue(z)); writefln("long '%s'", FullTextValue(a)); } </dcode>
Thanks. Out of curiosity (note: I haven't run this example yet), is 52 a magic number for the floating point types in D? Is there a way at runtime to get at the number of digits available after the decimal point depending on whether it's a float, double or real?
I think he's taking that from the number of mantissa bits in IEEE double precision floating point. There certainly can't be more meaningful decimal digits of accuracy than there are binary digits. Don could probably tell it much better than me, but it works out to be about 16 decimal digits of accuracy. Goes something like this: Smallest thing you can represent in an IEEE double with the mantissa only is 2^-52 (or maybe 2^-53?). Which works out to about 10^-16, so that means with decimal point, only about 16 digits can have meaning. So use 20 and you should be safe -- for doubles anyway. For floats it's about 8 decimal digits. decimal digits of precision: http://www.digitalmars.com/d/property.html - "Properties for Floating Point Types" --bb
Jul 18 2007
parent reply Joe <Joe_member pathlink.com> writes:
Bill Baxter wrote:
 Joe wrote:
 Derek Parnell wrote:
 On Wed, 18 Jul 2007 21:28:47 -0500, Joe wrote:

 How to do get a full string representation of a floating point?

 I've tried toString() on a floating point and the default precision 
 for numbers after the decimal point is 6.  I've also tried using 
 format strings, but I can't seem to get a full textual 
 representation of a floating point.  Is there some trick I'm missing?
Try this ... <dcode> import std.stdio; import std.string; string FullTextValue(T)(T x) { string s; static if(is (T:long)) const fmt = "%-52d"; else static if(is (T:real)) const fmt = "%52.52f"; else const fmt = "%-s"; s = std.string.format( fmt, x); for (int i = s.length-1; i >= 0; i--) { if (s[i] == '.') { s.length = i+2; break; } if ((s[i] != '0' && s[i] != ' ') || (i == 0)) { s.length = i+1; break; } } return s; } void main() { real x; double y; float z; long a; x = 12345678901234567890.1234567890123456789; y = x; z = x; a = cast(typeof(a))x; writefln("real '%s'", FullTextValue(x)); writefln("double '%s'", FullTextValue(y)); writefln("float '%s'", FullTextValue(z)); writefln("long '%s'", FullTextValue(a)); x = 0.1234567890123456789; y = x; z = x; a = cast(typeof(a))x; writefln("real '%s'", FullTextValue(x)); writefln("double '%s'", FullTextValue(y)); writefln("float '%s'", FullTextValue(z)); writefln("long '%s'", FullTextValue(a)); } </dcode>
Thanks. Out of curiosity (note: I haven't run this example yet), is 52 a magic number for the floating point types in D? Is there a way at runtime to get at the number of digits available after the decimal point depending on whether it's a float, double or real?
I think he's taking that from the number of mantissa bits in IEEE double precision floating point. There certainly can't be more meaningful decimal digits of accuracy than there are binary digits. Don could probably tell it much better than me, but it works out to be about 16 decimal digits of accuracy. Goes something like this: Smallest thing you can represent in an IEEE double with the mantissa only is 2^-52 (or maybe 2^-53?). Which works out to about 10^-16, so that means with decimal point, only about 16 digits can have meaning. So use 20 and you should be safe -- for doubles anyway. For floats it's about 8 decimal digits. decimal digits of precision: http://www.digitalmars.com/d/property.html - "Properties for Floating Point Types" --bb
I appreciate the explanation. While I still don't grasp all the details, this helps a lot.
Jul 18 2007
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Joe wrote:
 Bill Baxter wrote:
 Joe wrote:
 Derek Parnell wrote:
 On Wed, 18 Jul 2007 21:28:47 -0500, Joe wrote:

 How to do get a full string representation of a floating point?

 I've tried toString() on a floating point and the default precision 
 for numbers after the decimal point is 6.  I've also tried using 
 format strings, but I can't seem to get a full textual 
 representation of a floating point.  Is there some trick I'm missing?
Try this ... <dcode> import std.stdio; import std.string; string FullTextValue(T)(T x) { string s; static if(is (T:long)) const fmt = "%-52d"; else static if(is (T:real)) const fmt = "%52.52f"; else const fmt = "%-s"; s = std.string.format( fmt, x); for (int i = s.length-1; i >= 0; i--) { if (s[i] == '.') { s.length = i+2; break; } if ((s[i] != '0' && s[i] != ' ') || (i == 0)) { s.length = i+1; break; } } return s; } void main() { real x; double y; float z; long a; x = 12345678901234567890.1234567890123456789; y = x; z = x; a = cast(typeof(a))x; writefln("real '%s'", FullTextValue(x)); writefln("double '%s'", FullTextValue(y)); writefln("float '%s'", FullTextValue(z)); writefln("long '%s'", FullTextValue(a)); x = 0.1234567890123456789; y = x; z = x; a = cast(typeof(a))x; writefln("real '%s'", FullTextValue(x)); writefln("double '%s'", FullTextValue(y)); writefln("float '%s'", FullTextValue(z)); writefln("long '%s'", FullTextValue(a)); } </dcode>
Thanks. Out of curiosity (note: I haven't run this example yet), is 52 a magic number for the floating point types in D? Is there a way at runtime to get at the number of digits available after the decimal point depending on whether it's a float, double or real?
I think he's taking that from the number of mantissa bits in IEEE double precision floating point. There certainly can't be more meaningful decimal digits of accuracy than there are binary digits. Don could probably tell it much better than me, but it works out to be about 16 decimal digits of accuracy. Goes something like this: Smallest thing you can represent in an IEEE double with the mantissa only is 2^-52 (or maybe 2^-53?). Which works out to about 10^-16, so that means with decimal point, only about 16 digits can have meaning. So use 20 and you should be safe -- for doubles anyway. For floats it's about 8 decimal digits. decimal digits of precision: http://www.digitalmars.com/d/property.html - "Properties for Floating Point Types" --bb
I appreciate the explanation. While I still don't grasp all the details, this helps a lot.
Maybe it helps to think of trying to store the number 1.000..0001 and consider how many zeros can go in there before the computer thinks it's just 1. That's roughly the number of sigificant digits you have. Another way of saying that is -- for what value of x does 1+2^-x give you just 1 using doubles? It's about x=52 because IEEE doubles have 52 mantissa bits (and there's an implicit 1 at the beginning that isn't stored in the mantissa). --bb
Jul 18 2007
prev sibling parent Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Joe wrote:
 I appreciate the explanation.  While I still don't grasp all the 
 details, this helps a lot.
The following may be helpful as a more in-depth treatment of the subject: http://en.wikipedia.org/wiki/IEEE_754 -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.org
Jul 19 2007