26

Any smart way to convert a float like this:

float f = 711989.98f;

into a decimal (or double) without losing precision?

I've tried:

decimal d = (decimal)f;
decimal d1 = (decimal)(Math.Round(f,2));
decimal d2 = Convert.ToDecimal(f);
Mac
2,34214 silver badges26 bronze badges
asked Apr 7, 2010 at 18:12
2
  • More details: I'm interfacing with an old webservice that sends this huge object that has some fields as float. When I do the conversion to decimal kaboom...no more pennies ! Commented Apr 7, 2010 at 18:32
  • if this is coming from a web service on the wire it is probably XML, which means no float or decimals - just strings. Look where these strings are converted to "internal" format Commented Apr 7, 2010 at 18:52

5 Answers 5

19

It's too late, the 8th digit was lost in the compiler. The float type can store only 7 significant digits. You'll have to rewrite the code, assigning to double or decimal will of course solve the problem.

answered Apr 7, 2010 at 18:22
Sign up to request clarification or add additional context in comments.

1 Comment

thanks I've changed the type of the field on mapped object from float to decimal and solved the conversion issue that was happening during deserialization.
5

This may be a compiler bug because it seems like a valid float should convert directly to a decimal. but it wont without losing resolution. Converting 125.609375 from float to decimal will lose resolution. However, converting it from float to double and then double to decimal will keep resolution.

 float float_val = 125.609375f;
 decimal bad_decimal_val = (decimal)float_val; //125.6094
 double double_val = (double)float_val;
 decimal good_decimal_val = (decimal)double_val;
answered Sep 6, 2017 at 3:27

1 Comment

converting from float to double doesn't magically add in lost decimal places. just use floating point literals without the 'f' at the end (those are doubles), or use decimal literals like 125.609375M.
2

You lost precision the moment you've written 711989.98f.

711989.98 is decimal. With f in the end you are asking the compiler to convert it to float. This conversion cannot be done without losing precision.

What you probably want is decimal d = 711989.98m. This will not lose precision.

Drew Noakes
313k174 gold badges704 silver badges770 bronze badges
answered Apr 7, 2010 at 18:23

1 Comment

Your example just uses a double, right? It could still lose precision for a different number. Just put an 'm' on the end and make the literal a decimal to start with.
2

try this

float y = 20;
decimal x = Convert.ToDecimal(y/100);
print("test: " + x);
Saeed Zhiany
2,1419 gold badges34 silver badges44 bronze badges
answered Jul 25, 2022 at 16:22

1 Comment

Please read How do I write a good answer?. While this code block may answer the OP's question, this answer would be much more useful if you explain how this code is different from the code in the question, what you've changed, why you've changed it and why that solves the problem without introducing others.
1

have you tried?

decimal.TryParse()

http://forums.asp.net/t/1161880.aspx

There are no implicit conversions between float/double and decimal. Implicit numeric conversions are always guaranteed to be without loss of precision or magnitude and will not cause an exception.

answered Apr 7, 2010 at 18:16

7 Comments

Implicit conversions are not guaranteed to be without loss of precision. Converting 9007199791611905 to double will yield 9007199791611904. Converting directly to float will yield 9007200328482816. Converting to double and then to float will yield 9007199254740992 (which is off by more than if the number had been converted directly to float). Further, while compilers allow implicit conversion from float to double, such conversions are far more likely to be erroneous than would be conversions from double to float which aren't allowed but should be.
@supercat apparently you can losslessly convert float to double. However converting double to float is likely to introduce errors, depending upon the specific double value in question.
@DrewNoakes: If one has used an iterative computation to compute an object's position using type double, and then wishes to draw it using graphics routines that accept float, conversion to float would lop off precision that would generally be useless even if retained; lopping off the precision would almost certainly be consistent with programmer intent. By contrast, if some code e.g. divides an int or long by a float and stores the result in a double, then unless the programmer explicitly cast the result of the division to float I would not presume that the programmer...
...actually intended that the division should only be performed with float precision. Given int x=16777217; float y=1.0f; do you think it more likely that a programmer who writes double z=x/y; would be expecting z to be 16777216.0 or 16777217.0? For that matter, even given float one=1.0f,ten=10.0f; double d=one/ten;, do you think a programmer would more likely be wanting d to receive the value 0.1f or 0.1 ?
@supercat, I see your point. I came to this question looking for information about loss of precision when converting from float/double to decimal (I am considering allowing this conversion in a deserialiser so that schemata can evolve this way), so was focusing primarily on loss of precision during a single conversion. For that my comment holds. Your perspective is interesting and valid, though a pitfall I'm aware of and avoid through careful selection of floating point type. I'm less familiar with decimal, especially wrt conversions from floats.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.