Velocity Reviews > converting float to double

# converting float to double

Dilip
Guest
Posts: n/a

 12-19-2006

Recently in our code, I ran into a situation where were stuffing a
float inside a double. The precision was extended automatically
because of that. To make a long story short, this caused problems
elsewhere in another part of the system where that figure was used for
some calculation and some eventual truncation led to the system going
haywire. So my question is, given this code:

int main()
{
float f = 59.89F;
/* the following line caused problems */
double d = f;

/* they ended up solving it like this */
f *= 1000.0;
double dd = (double)f / 1000.0;

return 0;
}

I see what is being done but why does the latter make the situation
better?
(consider 'f' in real life to hold stock prices)

mark_bluemel@pobox.com
Guest
Posts: n/a

 12-19-2006

Dilip wrote:
> Recently in our code, I ran into a situation where were stuffing a
> float inside a double. The precision was extended automatically
> because of that. To make a long story short, this caused problems
> elsewhere in another part of the system where that figure was used for
> some calculation and some eventual truncation led to the system going
> haywire. So my question is, given this code:
>
> int main()
> {
> float f = 59.89F;
> /* the following line caused problems */
> double d = f;
>
> /* they ended up solving it like this */
> f *= 1000.0;
> double dd = (double)f / 1000.0;
>
> return 0;
> }
>
> I see what is being done but why does the latter make the situation
> better?
> (consider 'f' in real life to hold stock prices)

Not a good idea...

Floating point is by its nature imprecise - multiplying by 1000 simply
adjusts the imprecision in a way which was helpful in this specific
case, but may not be helpful in all cases (AFAIK).

If you want to safely and accurately handle this sort of data, sources
such as http://www2.hursley.ibm.com/decimal/ may be helpful.

CBFalconer
Guest
Posts: n/a

 12-19-2006
Dilip wrote:
>
> Recently in our code, I ran into a situation where were stuffing a
> float inside a double. The precision was extended automatically
> because of that. To make a long story short, this caused problems
> elsewhere in another part of the system where that figure was used
> for some calculation and some eventual truncation led to the system
> going haywire. So my question is, given this code:
>
> int main()
> {
> float f = 59.89F;
> /* the following line caused problems */
> double d = f;
>
> /* they ended up solving it like this */
> f *= 1000.0;
> double dd = (double)f / 1000.0;
>
> return 0;
> }
>
> I see what is being done but why does the latter make the
> situation better?
> (consider 'f' in real life to hold stock prices)

It doesn't. It should make it dead wrong. Either you are not
showing the real situation or you have a compiler bug.

Alternatively, if you are depending on exact values from floats
and/or doubles, your code is broken. Since stock prices (today)
are decimalized, just use a normalized integer of suitable size.
Read Knuth (TAOCP) on floating point and expected errors.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

pete
Guest
Posts: n/a

 12-19-2006
Dilip wrote:
>
> Recently in our code, I ran into a situation where were stuffing a
> float inside a double. The precision was extended automatically
> because of that. To make a long story short, this caused problems
> elsewhere in another part of the system where that figure was used for
> some calculation and some eventual truncation led to the system going
> haywire. So my question is, given this code:
>
> int main()
> {
> float f = 59.89F;
> /* the following line caused problems */
> double d = f;
>
> /* they ended up solving it like this */
> f *= 1000.0;
> double dd = (double)f / 1000.0;
>
> return 0;
> }
>
> I see what is being done but why does the latter make the situation
> better?
> (consider 'f' in real life to hold stock prices)

I wouldn't have used a float variable like that to begin with.

Use float,
when you need the smallest floating point type.

Use long double,
when you need the floating point type
with most precision and or range.

Use double,
all the rest of the time.

--
pete

Dilip
Guest
Posts: n/a

 12-19-2006
CBFalconer wrote:
> Dilip wrote:
> >
> > Recently in our code, I ran into a situation where were stuffing a
> > float inside a double. The precision was extended automatically
> > because of that. To make a long story short, this caused problems
> > elsewhere in another part of the system where that figure was used
> > for some calculation and some eventual truncation led to the system
> > going haywire. So my question is, given this code:
> >
> > int main()
> > {
> > float f = 59.89F;
> > /* the following line caused problems */
> > double d = f;
> >
> > /* they ended up solving it like this */
> > f *= 1000.0;
> > double dd = (double)f / 1000.0;
> >
> > return 0;
> > }
> >
> > I see what is being done but why does the latter make the
> > situation better?
> > (consider 'f' in real life to hold stock prices)

>
> It doesn't. It should make it dead wrong. Either you are not
> showing the real situation or you have a compiler bug.

I am showing exactly what is being done in our codebase. Why do you
say there is a compiler bug? If you try the example, as soon as the
1st line is executed the variable f contains 59.889999. After its
stuffed into double d, it becomes 59.889999389648437 (I know these
values vary after a certain decimal position). The
multiplication/division to 1000.0 however produces 59.890000000000001
in dd. The management somehow feels thats a more "accurate"
representation. I guess after rounding off to 2 decimal places they
expected 59.89 but a bug somewhere in the code ensured that the former
case got rounded off to 59.88. It was off by a penny and that
triggered major problems in other calculations.

> Since stock prices (today)
> are decimalized, just use a normalized integer of suitable size.
> Read Knuth (TAOCP) on floating point and expected errors.

I am not exactly unfamiliar with floating point representations and its
associated accuracy related problems but I think this is the first time
I am working in a domain where such problems crop up on a more frequent
basis. Could you please elaborate on that "normalized integer of
suitable size"?

Keith Thompson
Guest
Posts: n/a

 12-19-2006
CBFalconer <(E-Mail Removed)> writes:
> Dilip wrote:
>> Recently in our code, I ran into a situation where were stuffing a
>> float inside a double. The precision was extended automatically
>> because of that. To make a long story short, this caused problems
>> elsewhere in another part of the system where that figure was used
>> for some calculation and some eventual truncation led to the system
>> going haywire. So my question is, given this code:
>>
>> int main()
>> {
>> float f = 59.89F;
>> /* the following line caused problems */
>> double d = f;
>>
>> /* they ended up solving it like this */
>> f *= 1000.0;
>> double dd = (double)f / 1000.0;
>>
>> return 0;
>> }
>>
>> I see what is being done but why does the latter make the
>> situation better?
>> (consider 'f' in real life to hold stock prices)

>
> It doesn't. It should make it dead wrong. Either you are not
> showing the real situation or you have a compiler bug.

Are you sure about that? The code multiplies f by 1000.0, then
divides the result by 1000.0. The *mathematical* result is the same,
but the way it's done is likely to change the rounding behavior
slightly. It's not likely to be a general solution to any problem.
It smacks of "cargo cult programming"; see
<http://www.catb.org/~esr/jargon/html/C/cargo-cult-programming.html>.

> Alternatively, if you are depending on exact values from floats
> and/or doubles, your code is broken. Since stock prices (today)
> are decimalized, just use a normalized integer of suitable size.
> Read Knuth (TAOCP) on floating point and expected errors.

Another good resource is Goldberg's paper "What Every Computer
floating" to find it.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

William Hughes
Guest
Posts: n/a

 12-19-2006

pete wrote:
> Dilip wrote:
> >
> > Recently in our code, I ran into a situation where were stuffing a
> > float inside a double. The precision was extended automatically
> > because of that. To make a long story short, this caused problems
> > elsewhere in another part of the system where that figure was used for
> > some calculation and some eventual truncation led to the system going
> > haywire. So my question is, given this code:
> >
> > int main()
> > {
> > float f = 59.89F;
> > /* the following line caused problems */
> > double d = f;
> >
> > /* they ended up solving it like this */
> > f *= 1000.0;
> > double dd = (double)f / 1000.0;
> >
> > return 0;
> > }
> >
> > I see what is being done but why does the latter make the situation
> > better?
> > (consider 'f' in real life to hold stock prices)

>
> I wouldn't have used a float variable like that to begin with.
>
> Use float,
> when you need the smallest floating point type.
>
> Use long double,
> when you need the floating point type
> with most precision and or range.
>
> Use double,
> all the rest of the time.
>

This comes squarely under the heading "If you can understand this

- William Hughes
> --
> pete

Random832
Guest
Posts: n/a

 12-19-2006
2006-12-19 <(E-Mail Removed)>,
pete wrote:
> Dilip wrote:
>>
>> Recently in our code, I ran into a situation where were stuffing a
>> float inside a double. The precision was extended automatically
>> because of that. To make a long story short, this caused problems
>> elsewhere in another part of the system where that figure was used for
>> some calculation and some eventual truncation led to the system going
>> haywire. So my question is, given this code:
>>
>> int main()
>> {
>> float f = 59.89F;
>> /* the following line caused problems */
>> double d = f;
>>
>> /* they ended up solving it like this */
>> f *= 1000.0;
>> double dd = (double)f / 1000.0;
>>
>> return 0;
>> }
>>
>> I see what is being done but why does the latter make the situation
>> better?
>> (consider 'f' in real life to hold stock prices)

>
> I wouldn't have used a float variable like that to begin with.
>
> Use float,
> when you need the smallest floating point type.
>
> Use long double,
> when you need the floating point type
> with most precision and or range.

Use integers,
when you need to be exact to within a known specific unit, such as
a dollar, cent, or Nth part of either.

> Use double,
> all the rest of the time.

Random832
Guest
Posts: n/a

 12-19-2006
2006-12-19 <(E-Mail Removed). com>,
Dilip wrote:
> I am not exactly unfamiliar with floating point representations and its
> associated accuracy related problems but I think this is the first time
> I am working in a domain where such problems crop up on a more frequent
> basis. Could you please elaborate on that "normalized integer of
> suitable size"?

Have an integer variable [probably type long or long long] counting the
number of cents (or thousandths of a dollar, or whatever). Doing your
weird cast thing fixed the error in that one particular case, but could
have introduced other errors elsewhere.

Dilip
Guest
Posts: n/a

 12-19-2006
Keith Thompson wrote:
> CBFalconer <(E-Mail Removed)> writes:
> > Dilip wrote:
> >> Recently in our code, I ran into a situation where were stuffing a
> >> float inside a double. The precision was extended automatically
> >> because of that. To make a long story short, this caused problems
> >> elsewhere in another part of the system where that figure was used
> >> for some calculation and some eventual truncation led to the system
> >> going haywire. So my question is, given this code:
> >>
> >> int main()
> >> {
> >> float f = 59.89F;
> >> /* the following line caused problems */
> >> double d = f;
> >>
> >> /* they ended up solving it like this */
> >> f *= 1000.0;
> >> double dd = (double)f / 1000.0;
> >>
> >> return 0;
> >> }
> >>
> >> I see what is being done but why does the latter make the
> >> situation better?
> >> (consider 'f' in real life to hold stock prices)

> >
> > It doesn't. It should make it dead wrong. Either you are not
> > showing the real situation or you have a compiler bug.

>
> Are you sure about that? The code multiplies f by 1000.0, then
> divides the result by 1000.0. The *mathematical* result is the same,
> but the way it's done is likely to change the rounding behavior
> slightly. It's not likely to be a general solution to any problem.
> It smacks of "cargo cult programming"; see
> <http://www.catb.org/~esr/jargon/html/C/cargo-cult-programming.html>.

I totally agree which is the reason why I posted to this NG to
understand what exactly is being solved by that 1000.0 workaround.

> Another good resource is Goldberg's paper "What Every Computer
> floating" to find it.

I came across that paper quite a few times in the past. I never
realized one day I would need to know that amount of detail. Do you
have any insights into that normalized integer thing everyone has been
pointing out so far? If one of you can give me an example, i'd
appreciate it.