float to double conversion question

  • Thread starter Thread starter sonic_soul
  • Start date Start date
S

sonic_soul

so my app uses float for money, and we are now consuming a webservice
that uses double for money. here is the problem i run into while
converting


float f1 = 23.32

double d1 = (double)f1;
d1=23.3199996948242

i understand that is because of the extra floating spaces (although it
still isnt making perfect sense to me, why wouldnt the extra floating
spaces just add 0's which would keep the number the same)

i suppose i could convert it to string and than parse double .. but
what is the best way to convert it keeping in mind currency with just
2 decimal places with best precision ?
 
sonic_soul said:
so my app uses float for money, and we are now consuming a webservice
that uses double for money. here is the problem i run into while
converting


float f1 = 23.32

double d1 = (double)f1;
d1=23.3199996948242

i understand that is because of the extra floating spaces (although it
still isnt making perfect sense to me, why wouldnt the extra floating
spaces just add 0's which would keep the number the same)

i suppose i could convert it to string and than parse double .. but
what is the best way to convert it keeping in mind currency with just
2 decimal places with best precision ?

You should never use float or double for currency. float and double are
approxamite data types, and they are only to be used for graphics,
scientific computing, and as intermediate types in mathematical
calculations, always to be follwed by rounding and converting to a decimal.

Use Decimal instead.

David
 
sonic_soul said:
so my app uses float for money, and we are now consuming a webservice
that uses double for money. here is the problem i run into while
converting

First of all: *never* use floating point values if you want an exact
rational number. If the rational number is 10 based (like all currencies
I know) you sholud use decimal.

Rational numbers have no exact representation in number systems where
the denominater contains prime factors that are not part of the number
systems base.
Example:
1/3 = 0.33333... (decimal, base 10)
= 0.01010101... (binary, base 2)
1/5 = 0.2 (exact; 5 is a prime factor of the number system base 10)
= 0.001100110011... (binary, base 2)
float f1 = 23.32

This was never 23.32 - but 10111.0101000111101011100 (binary) which is
exactly 23.31999969482421875 (decimal).

double d1 = (double)f1;
d1=23.3199996948242
i understand that is because of the extra floating spaces (although it
still isnt making perfect sense to me, why wouldnt the extra floating
spaces just add 0's which would keep the number the same)

It *will* add zeros! - but in the binary representation!

i suppose i could convert it to string and than parse double .. but
what is the best way to convert it keeping in mind currency with just
2 decimal places with best precision ?

To lock the stable door after the horse has bolted yo must apply a
constraint. E.g. "choose the closest rational number with the
denominator 100". This is called rounding!
You must do this /after/ the connversion to a more precise
representation, since the above number already /is/ the closest number
in the float representation according to this constraint.


Marcel
 
thank you for that comment. It is definitely good thinking and i wish
you were in charge of designing the app I am currently supporting.

if i could design this system i would not put my self in the predicament
that i'm in.

for now I still need to make it work in the way it is written as we have
no resources to re-design the whole app to not use floats etc etc.

so if anyone has any comment on my original post it is very welcome.
 
Thank you Marcel.
That was very informative!!

I'll have to do some reading in regards to how those types really work
!!! c# has shielded me from the trouble and im guessing same happened
for whoever designed this system.
 
2 questions:

you said:
It *will* add zeros! - but in the binary representation!
and than:
This was never 23.32 - but 10111.0101000111101011100

well if appears that it in fact did not add 0's to the decimal places
that were not visible in the initial 23.32 assignment :/

i guess i am not looking at it right which brings me to the second
question:

How can i come up with the binary representation of those numbers ? i
mean.. if a float is 2.2 and the binary number will show all 9 decimal
places ? is there a good place i can go to learn about this ?

thank you.
 
sonic_soul said:
so my app uses float for money, and we are now consuming a webservice
that uses double for money. here is the problem i run into while
converting

float f1 = 23.32

double d1 = (double)f1;
d1=23.3199996948242

i understand that is because of the extra floating spaces (although it
still isnt making perfect sense to me, why wouldnt the extra floating
spaces just add 0's which would keep the number the same)

Because binary 0s don't amount to decimal 0s.
i suppose i could convert it to string and than parse double .. but
what is the best way to convert it keeping in mind currency with just
2 decimal places with best precision ?

Use the decimal type.

See http://www.pobox.com/~skeet/csharp/floatingpoint.html for more
information.
 
SoniC said:
2 questions:

you said:


and than:
This was never 23.32 - but 10111.0101000111101011100

well if appears that it in fact did not add 0's to the decimal places
that were not visible in the initial 23.32 assignment :/

I didn't catch your question exactly, but I guess you wonder why
23.32.ToString() returns "23.32".
Well Microsoft does not like support calls :) so the default format for
the string conversion rounds to slightly less precision than float could
provide (anyway a fractional number of digits).

Other languages like perl don't do this. They print as many digits as
required to represent the float definite. This often gives an output
like 23.31999....

i guess i am not looking at it right which brings me to the second
question:

How can i come up with the binary representation of those numbers ? i
mean.. if a float is 2.2 and the binary number will show all 9 decimal
places ? is there a good place i can go to learn about this ?

Sorry, no idea, but the web is large...


Marcel
 
sonic_soul said:
so my app uses float for money, and we are now consuming a webservice
that uses double for money. here is the problem i run into while
converting


float f1 = 23.32

double d1 = (double)f1;
d1=23.3199996948242

i understand that is because of the extra floating spaces (although it
still isnt making perfect sense to me, why wouldnt the extra floating
spaces just add 0's which would keep the number the same)

It does just add 0's, but that set of bits in a double is equivalent to
the 23.3199996948242 value that you're seeing.
i suppose i could convert it to string and than parse double .. but
what is the best way to convert it keeping in mind currency with just
2 decimal places with best precision ?

Unfortunately, I think that this method is the only one that will work.

I know you've gotten all the responses saying that you should not use
float for currency, but since you seem to be stuck with it, something like:

public double MyConvert( float f) {
return double.Parse( f.ToString( "0.00"));
}

might be what you're looking for. You can play around with the
f.ToString() format specification, if that's appropriate.
 
sonic_soul said:
so my app uses float for money, and we are now consuming a webservice
that uses double for money. here is the problem i run into while
converting


float f1 = 23.32

double d1 = (double)f1;
d1=23.3199996948242

i understand that is because of the extra floating spaces (although it
still isnt making perfect sense to me, why wouldnt the extra floating
spaces just add 0's which would keep the number the same)

It does just add 0's, but that set of bits in a double is equivalent to
the 23.3199996948242 value that you're seeing.
i suppose i could convert it to string and than parse double .. but
what is the best way to convert it keeping in mind currency with just
2 decimal places with best precision ?

Unfortunately, I think that this method is the only one that will work.

I know you've gotten all the responses saying that you should not use
float for currency, but since you seem to be stuck with it, something like:

public double MyConvert( float f) {
return double.Parse( f.ToString( "0.00"));
}

might be what you're looking for. You can play around with the
f.ToString() format specification, if that's appropriate.
 
Back
Top