double to string retain "precision"

Discussion in 'C++' started by rjsteele, Mar 10, 2011.

  1. rjsteele

    rjsteele Guest

    How do I retain the value (precision) of the double as a string?

    double d = 117.9879878988754135
    stringstream ss;
    ss << d;

    cout << ss.str() << endl;

    Output: 117.987 ---------- I want this to be the same as the
    initial double.

    Thanks in advance.
    rjsteele, Mar 10, 2011
    #1
    1. Advertising

  2. rjsteele

    rjsteele Guest

    On Mar 9, 5:00 pm, rjsteele <> wrote:
    > How do I retain the value (precision) of the double as a string?
    >
    > double d = 117.9879878988754135
    > stringstream ss;
    > ss << d;
    >
    > cout << ss.str()  << endl;
    >
    > Output:   117.987  ---------- I want this to be the same as the
    > initial double.
    >
    > Thanks in advance.


    I think I go it.

    std::stringstream ss; ss <<
    std::setprecision(std::numeric_limits<double>::digits10); ss << d;
    return ss.str();
    rjsteele, Mar 10, 2011
    #2
    1. Advertising

  3. rjsteele

    SG Guest

    rjsteele wrote:
    > rjsteele wrote:
    >
    > > How do I retain the value (precision) of the double as a string?

    >
    > I think I go it.
    >
    >  std::stringstream ss;
    > ss << std::setprecision(std::numeric_limits<double>::digits10);
    > ss << d;
    > return ss.str();


    I don't recall how exactly digits10 was defined but in case double
    refers to an IEEE-754 64-bit float on your machine, you will need 17
    significant decimal digits for a lossless double-string-double
    roundtrip. For a lossless string-double-string roundtrip (*) you need
    to limit your strings to 15 significant decimal digits

    (* lossless in the sense that the numbers the strings represent are
    the same and not necessarily the strings itself, so "0.15" would be
    equal to "0.1500" for example)

    Cheers!
    SG
    SG, Mar 10, 2011
    #3
  4. rjsteele <> wrote:
    > How do I retain the value (precision) of the double as a string?


    In general, you can't. Most floating point values have an infinite
    decimal representation.

    If you want a certain amount of decimals, use the precision()
    modifier.
    Juha Nieminen, Mar 10, 2011
    #4
  5. rjsteele

    Fred Zwarts Guest

    "Juha Nieminen" <> wrote in message
    news:4d7886fa$0$2892$
    > rjsteele <> wrote:
    >> How do I retain the value (precision) of the double as a string?

    >
    > In general, you can't. Most floating point values have an infinite
    > decimal representation.


    No. In many cases foating point values are stored as finite numbers with base 2.
    As 2 is a divisor of 10, a finite number in base 2 can be represented as a finite number in base 10.
    (But not the other way around. 1/5 = 0.2 is not a finite number in base 2.)
    Fred Zwarts, Mar 10, 2011
    #5
  6. rjsteele

    James Kanze Guest

    On Mar 10, 8:08 am, Juha Nieminen <> wrote:
    > rjsteele <> wrote:
    > > How do I retain the value (precision) of the double as a string?


    > In general, you can't. Most floating point values have an infinite
    > decimal representation.


    No. All can be represented exactly: ten is a multiple of 2, so for n
    bits precision in machine format, you are guaranteed an exact
    representation with at most n decimal digits.

    Of course, n is typically 52, and only a very small subset of 52 digit
    numbers correspond exactly to a double. And since in most cases, it's
    highly unlikely that the double corresponded to the exact value to
    begin
    with, you don't use 52 digits.

    --
    James Kanze
    James Kanze, Mar 10, 2011
    #6
  7. rjsteele

    Öö Tiib Guest

    On Mar 10, 10:59 pm, James Kanze <> wrote:
    > On Mar 10, 8:08 am, Juha Nieminen <> wrote:
    >
    > > rjsteele <> wrote:
    > > > How do I retain the value (precision) of the double as a string?

    > > In general, you can't. Most floating point values have an infinite
    > > decimal representation.

    >
    > No.  All can be represented exactly: ten is a multiple of 2, so for n
    > bits precision in machine format, you are guaranteed an exact
    > representation with at most n decimal digits.
    >
    > Of course, n is typically 52, and only a very small subset of 52 digit
    > numbers correspond exactly to a double.  And since in most cases, it's
    > highly unlikely that the double corresponded to the exact value to
    > begin
    > with, you don't use 52 digits.


    52 decimal digits? That means your float types have over 180 bits?
    Öö Tiib, Mar 11, 2011
    #7
  8. rjsteele

    rjsteele Guest

    On Mar 10, 5:49 pm, Öö Tiib <> wrote:
    > On Mar 10, 10:59 pm, James Kanze <> wrote:
    >
    >
    >
    >
    >
    > > On Mar 10, 8:08 am, Juha Nieminen <> wrote:

    >
    > > > rjsteele <> wrote:
    > > > > How do I retain the value (precision) of the double as a string?
    > > > In general, you can't. Most floating point values have an infinite
    > > > decimal representation.

    >
    > > No.  All can be represented exactly: ten is a multiple of 2, so for n
    > > bits precision in machine format, you are guaranteed an exact
    > > representation with at most n decimal digits.

    >
    > > Of course, n is typically 52, and only a very small subset of 52 digit
    > > numbers correspond exactly to a double.  And since in most cases, it's
    > > highly unlikely that the double corresponded to the exact value to
    > > begin
    > > with, you don't use 52 digits.

    >
    > 52 decimal digits? That means your float types have over 180 bits?


    Thanks for all the responses.
    rjsteele, Mar 11, 2011
    #8
  9. On Mar 9, 7:06 pm, rjsteele <> wrote:
    > On Mar 9, 5:00 pm, rjsteele <> wrote:
    >
    > > How do I retain the value (precision) of the double as a string?

    >
    > > double d = 117.9879878988754135
    > > stringstream ss;
    > > ss << d;

    >
    > > cout << ss.str()  << endl;

    >
    > > Output:   117.987  ---------- I want this to be the same as the
    > > initial double.

    >
    > > Thanks in advance.

    >
    > I think I go it.
    >
    >  std::stringstream ss;   ss <<
    > std::setprecision(std::numeric_limits<double>::digits10);   ss << d;
    > return ss.str();


    Use

    std::numeric_limits<double>::digits10 + 1

    instead.

    KHD
    Keith H Duggar, Mar 11, 2011
    #9
  10. rjsteele

    Fred Zwarts Guest

    "Öö Tiib" <> wrote in message
    news:
    > On Mar 10, 10:59 pm, James Kanze <> wrote:
    >> On Mar 10, 8:08 am, Juha Nieminen <> wrote:
    >>
    >>> rjsteele <> wrote:
    >>>> How do I retain the value (precision) of the double as a string?
    >>> In general, you can't. Most floating point values have an infinite
    >>> decimal representation.

    >>
    >> No. All can be represented exactly: ten is a multiple of 2, so for n
    >> bits precision in machine format, you are guaranteed an exact
    >> representation with at most n decimal digits.
    >>
    >> Of course, n is typically 52, and only a very small subset of 52
    >> digit numbers correspond exactly to a double. And since in most
    >> cases, it's highly unlikely that the double corresponded to the
    >> exact value to begin
    >> with, you don't use 52 digits.

    >
    > 52 decimal digits? That means your float types have over 180 bits?


    No.

    n bits corresponds with n decimal digits if printed in full precision.
    Numbers are nomally normalized such that the mantisse is a fractional
    number 0.5 <= M < 0.25.
    Each bit corresponds with one of the following values:

    1/2 = 0.5
    1/4 = 0.25
    1/8 = 0.125
    etc.

    The position of the last decimal shifts one place to the right for each bit..
    Since the bit for the value 1/2 is always non-zero,
    the total length of the decimal representation is always smaller or equal to
    the number of bits.
    Fred Zwarts, Mar 11, 2011
    #10
  11. rjsteele

    Fred Zwarts Guest

    "Fred Zwarts" <> wrote in message
    news:ildds2$129$
    > "Öö Tiib" <> wrote in message
    > news:
    >> On Mar 10, 10:59 pm, James Kanze <> wrote:
    >>> On Mar 10, 8:08 am, Juha Nieminen <> wrote:
    >>>
    >>>> rjsteele <> wrote:
    >>>>> How do I retain the value (precision) of the double as a string?
    >>>> In general, you can't. Most floating point values have an infinite
    >>>> decimal representation.
    >>>
    >>> No. All can be represented exactly: ten is a multiple of 2, so for n
    >>> bits precision in machine format, you are guaranteed an exact
    >>> representation with at most n decimal digits.
    >>>
    >>> Of course, n is typically 52, and only a very small subset of 52
    >>> digit numbers correspond exactly to a double. And since in most
    >>> cases, it's highly unlikely that the double corresponded to the
    >>> exact value to begin
    >>> with, you don't use 52 digits.

    >>
    >> 52 decimal digits? That means your float types have over 180 bits?

    >
    > No.
    >
    > n bits corresponds with n decimal digits if printed in full precision.
    > Numbers are nomally normalized such that the mantisse is a fractional
    > number 0.5 <= M < 0.25.


    Sorry, that should be 1 < M <= 0.5.
    The bit for the value 1/2 is always non-zero.


    > Each bit corresponds with one of the following values:
    >
    > 1/2 = 0.5
    > 1/4 = 0.25
    > 1/8 = 0.125
    > etc.
    >
    > The position of the last decimal shifts one place to the right for
    > each bit.. Since the bit for the value 1/2 is always non-zero,
    > the total length of the decimal representation is always smaller or
    > equal to the number of bits.
    Fred Zwarts, Mar 11, 2011
    #11
  12. James Kanze <> wrote:
    > On Mar 10, 8:08 am, Juha Nieminen <> wrote:
    >> rjsteele <> wrote:
    >> > How do I retain the value (precision) of the double as a string?

    >
    >> In general, you can't. Most floating point values have an infinite
    >> decimal representation.

    >
    > No. All can be represented exactly: ten is a multiple of 2,


    I suppose I'll have to stand corrected. I got confused by the
    conversion in the other direction (ie. not all values in base 10
    can be represented as floating point of base 2).

    > so for n
    > bits precision in machine format, you are guaranteed an exact
    > representation with at most n decimal digits.


    Only if you use the exponential notation (ie. "<base>e<exponent>").
    If you wrote it as a decimal value, it could take hundreds of digits
    (after all, the maximum value of a double-precision floating point is
    something like 10^300).
    Juha Nieminen, Mar 11, 2011
    #12
  13. rjsteele

    James Kanze Guest

    On Mar 11, 4:53 pm, Juha Nieminen <> wrote:
    > James Kanze <> wrote:
    > > On Mar 10, 8:08 am, Juha Nieminen <> wrote:
    > >> rjsteele <> wrote:
    > >> > How do I retain the value (precision) of the double as a string?


    > >> In general, you can't. Most floating point values have an infinite
    > >> decimal representation.


    > > No. All can be represented exactly: ten is a multiple of 2,


    > I suppose I'll have to stand corrected. I got confused by the
    > conversion in the other direction (ie. not all values in base
    > 10 can be represented as floating point of base 2).


    > > so for n bits precision in machine format, you are
    > > guaranteed an exact representation with at most n decimal
    > > digits.


    > Only if you use the exponential notation (ie.
    > "<base>e<exponent>"). If you wrote it as a decimal value, it
    > could take hundreds of digits (after all, the maximum value of
    > a double-precision floating point is something like 10^300).


    Good point. But it's worse than you think: the generated
    notation has nothing to do with; the only important part is the
    actual value. For an IEEE double:

    -- If the value is between 0.5 and 1.0 (logical exponent 0),
    the value can be written exactly in at most 53 digits, for
    the reason I explained.

    -- If the value is larger than 2^53, the exact value is an
    integer. Since DBL_MAX is something e307, it takes at most
    307 digits. On the other hand, the value can be 2^1023
    (even larger in fact, but less than 2^1024), and 2^1023
    requires 308 digits to represent exactly. (The value is
    roughly 9e307, and is not a multiple of 10, so will require
    a units digit which is not 0.) Thus, there are values which
    require 308 digits.

    -- For exponents less than 0, I'm too lazy to do the exact
    analysis, but I get the feeling that they will never require
    more digits than 308. Unlike positive values, increasing
    the binary exponant quickly starts introducing 0's to the
    right of the decimal. I'll leave the detailed analysis and
    the proof to others, but I'm fairly convinced that it can't
    be worse than 308 + 53. Which is still a finit number of
    digits.

    --
    James Kanze
    James Kanze, Mar 11, 2011
    #13
  14. rjsteele

    Jorgen Grahn Guest

    On Thu, 2011-03-10, Juha Nieminen wrote:
    > rjsteele <> wrote:
    >> How do I retain the value (precision) of the double as a string?

    >
    > In general, you can't. Most floating point values have an infinite
    > decimal representation.


    But all of them have a finite hexadecimal representation. I don't
    remember if those are part of C++ (they are in C99) and I have no idea
    how to print in that format using iostreams, and they would be
    unreadable for normal people ... but if you need "lossless printing"
    that's an option.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Mar 13, 2011
    #14
  15. rjsteele

    Jorgen Grahn Guest

    On Sun, 2011-03-13, Jorgen Grahn wrote:
    > On Thu, 2011-03-10, Juha Nieminen wrote:
    >> rjsteele <> wrote:
    >>> How do I retain the value (precision) of the double as a string?

    >>
    >> In general, you can't. Most floating point values have an infinite
    >> decimal representation.

    >
    > But all of them have a finite hexadecimal representation. I don't
    > remember if those are part of C++ (they are in C99) and I have no idea
    > how to print in that format using iostreams, and they would be
    > unreadable for normal people ... but if you need "lossless printing"
    > that's an option.


    And now I saw the other part of the thread, e.g.
    <4d7a5386$0$2814$>. Ah, I made the same mistake as
    Juha.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Mar 13, 2011
    #15
  16. rjsteele

    Öö Tiib Guest

    On Mar 13, 4:49 pm, Pete Becker <> wrote:
    > > On Thu, 2011-03-10, Juha Nieminen wrote:
    > >> rjsteele <> wrote:
    > >>> How do I retain the value (precision) of the double as a string?

    >
    > >> In general, you can't. Most floating point values have an infinite
    > >> decimal representation.

    >
    > The thing to keep in mind here is that because of the limited precision
    > of the floating-point value it doesn't necessarily represent the
    > "exact" result (i.e. the result you'd get with unbounded precision). In
    > many cases, if you've done the math correctly, the result is the
    > floating-point value that's closest to the true value. When you convert
    > that value to decimal you can't get the "exact" result; it just isn't
    > there. Instead, you should get a decimal representation that can be
    > converted back to floating-point and give you the original
    > floating-point value. There are lots of decimal values that will
    > satisfy that requirement, and there's no good reason to choose one with
    > lots of digits over one with fewer.


    Yes but if to think of it then they are right that IEEE doubles do
    have always finite decimal representation, so exact result is always
    there. Reverse is not true so majority of decimal values can not be
    represented as exact IEEE doubles.
    Öö Tiib, Mar 13, 2011
    #16
  17. rjsteele

    Fred Zwarts Guest

    "Pete Becker" <> wrote in message
    news:201103131354034756-pete@versatilecodingcom
    > On 2011-03-13 12:01:38 -0400, Öö Tiib said:
    >
    >> On Mar 13, 4:49 pm, Pete Becker <> wrote:
    >>>> On Thu, 2011-03-10, Juha Nieminen wrote:
    >>>>> rjsteele <> wrote:
    >>>>>> How do I retain the value (precision) of the double as a string?
    >>>
    >>>>> In general, you can't. Most floating point values have an infinite
    >>>>> decimal representation.
    >>>
    >>> The thing to keep in mind here is that because of the limited
    >>> precision of the floating-point value it doesn't necessarily
    >>> represent the "exact" result (i.e. the result you'd get with
    >>> unbounded precision). In many cases, if you've done the math
    >>> correctly, the result is the floating-point value that's closest to
    >>> the true value. When you convert that value to decimal you can't
    >>> get the "exact" result; it just isn't there. Instead, you should
    >>> get a decimal representation that can be converted back to
    >>> floating-point and give you the original floating-point value.
    >>> There are lots of decimal values that will satisfy that
    >>> requirement, and there's no good reason to choose one with lots of
    >>> digits over one with fewer.

    >>
    >> Yes but if to think of it then they are right that IEEE doubles do
    >> have always finite decimal representation, so exact result is always
    >> there.

    >
    > I think that's what I just said, although I don't know who "they" are.
    > You can always create a finite decimal representation that can be
    > translated back to the original floating-point value.


    Not only one that can be translated back to the same original floating point number
    (after rounding), but even one that represents exactly the same value (without rounding).
    Only the representation differs, the value of the decimal representation is exactly the same
    as that of the original (binairy) floating point representation.
    There is only one decimal representation that exactly matches the binairy representation.
    (There are, of course, many that match within the precision of the binairy representation.)
    Fred Zwarts, Mar 14, 2011
    #17
  18. rjsteele

    James Kanze Guest

    On Mar 13, 7:38 am, Jorgen Grahn <> wrote:
    > On Thu, 2011-03-10, Juha Nieminen wrote:
    > > rjsteele <> wrote:
    > >> How do I retain the value (precision) of the double as a string?


    > > In general, you can't. Most floating point values have an infinite
    > > decimal representation.


    > But all of them have a finite hexadecimal representation.


    Maybe. I've worked on machines which used a decimal floating
    point format (but that was long before C++). A decimal floating
    point will not have a finite hexadecimal representation (0.2,
    for example), since the prime factors of 10 are 2 and 5, and 1/5
    doesn't have a finite hexadecimal representation. (A binary
    floating point will have a finite decimal representation, since
    2 is a factor of 10.)

    > I don't
    > remember if those are part of C++ (they are in C99) and I have no idea
    > how to print in that format using iostreams, and they would be
    > unreadable for normal people ... but if you need "lossless printing"
    > that's an option.


    They're not part of C++, and as for lossless... If you write and
    then read on the same machine, you can obtain "lossless" for any
    base. If you don't, what does it mean: you write from a machine
    with 120 floating point (double on an old CDC, for example), and
    you read on a machine with 64 bit doubles. How can you obtain
    lossless?

    --
    James Kanze
    James Kanze, Mar 14, 2011
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Daniel Geisenhoff

    Bug in double precision computing?

    Daniel Geisenhoff, Jul 29, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    324
    Shan Plourde
    Jul 29, 2004
  2. Wolfgang
    Replies:
    4
    Views:
    5,104
    Andrew Hobbs
    Feb 24, 2004
  3. Replies:
    5
    Views:
    204,424
  4. Andersen

    double precision vs. integers

    Andersen, Dec 18, 2005, in forum: Java
    Replies:
    11
    Views:
    974
    Andersen
    Dec 20, 2005
  5. Sydex
    Replies:
    12
    Views:
    6,452
    Victor Bazarov
    Feb 17, 2005
Loading...

Share This Page