Velocity Reviews > C++ > double to string retain "precision"

# double to string retain "precision"

Fred Zwarts
Guest
Posts: n/a

 03-11-2011
"Fred Zwarts" <(E-Mail Removed)> wrote in message
news:ildds2\$129\$(E-Mail Removed)
> "Öö Tiib" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)
>> On Mar 10, 10:59 pm, James Kanze <(E-Mail Removed)> wrote:
>>> On Mar 10, 8:08 am, Juha Nieminen <(E-Mail Removed)> wrote:
>>>
>>>> rjsteele <(E-Mail Removed)> 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.

Juha Nieminen
Guest
Posts: n/a

 03-11-2011
James Kanze <(E-Mail Removed)> wrote:
> On Mar 10, 8:08 am, Juha Nieminen <(E-Mail Removed)> wrote:
>> rjsteele <(E-Mail Removed)> 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).

James Kanze
Guest
Posts: n/a

 03-11-2011
On Mar 11, 4:53 pm, Juha Nieminen <(E-Mail Removed)> wrote:
> James Kanze <(E-Mail Removed)> wrote:
> > On Mar 10, 8:08 am, Juha Nieminen <(E-Mail Removed)> wrote:
> >> rjsteele <(E-Mail Removed)> 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

Jorgen Grahn
Guest
Posts: n/a

 03-13-2011
On Thu, 2011-03-10, Juha Nieminen wrote:
> rjsteele <(E-Mail Removed)> 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
Guest
Posts: n/a

 03-13-2011
On Sun, 2011-03-13, Jorgen Grahn wrote:
> On Thu, 2011-03-10, Juha Nieminen wrote:
>> rjsteele <(E-Mail Removed)> 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\$(E-Mail Removed)>. Ah, I made the same mistake as
Juha.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Öö Tiib
Guest
Posts: n/a

 03-13-2011
On Mar 13, 4:49*pm, Pete Becker <(E-Mail Removed)> wrote:
> > On Thu, 2011-03-10, Juha Nieminen wrote:
> >> rjsteele <(E-Mail Removed)> 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.

Fred Zwarts
Guest
Posts: n/a

 03-14-2011
"Pete Becker" <(E-Mail Removed)> 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 <(E-Mail Removed)> wrote:
>>>> On Thu, 2011-03-10, Juha Nieminen wrote:
>>>>> rjsteele <(E-Mail Removed)> 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.)

James Kanze
Guest
Posts: n/a

 03-14-2011
On Mar 13, 7:38 am, Jorgen Grahn <(E-Mail Removed)> wrote:
> On Thu, 2011-03-10, Juha Nieminen wrote:
> > rjsteele <(E-Mail Removed)> 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