### Thread: loss of precision float to int in c

1. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Nov 2004
Posts
6
Rep Power
0

#### loss of precision float to int in c

I'm trying to do:

int copyinput;
float input;

copyinput = (int) (input * 100);

input lets say is: 8888.88

copyinput holds: 888887

How can I overcome this inprecision without big computational efforts.
Thanks.
2. No Profile Picture
Contributing User
Devshed Novice (500 - 999 posts)

Join Date
Jan 2004
Location
Constant Limbo
Posts
989
Rep Power
366
why not just leave it as a float?
3. No Profile Picture
Contributing User
Devshed Novice (500 - 999 posts)

Join Date
Jun 2003
Posts
705
Rep Power
15
floats and float math is inherently imprecise.

You can round, you can do whatever, and some tiny discrepency will still creep in.

4. No Profile Picture
Contributing User
Devshed Novice (500 - 999 posts)

Join Date
May 2004
Location
Posts
880
Rep Power
14
You could always do
copyinput = (int) (input * 100 + 0.5);

which will round off, rather than down.
5. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Nov 2004
Posts
6
Rep Power
0
Originally Posted by jasonvene
floats and float math is inherently imprecise.

You can round, you can do whatever, and some tiny discrepency will still creep in.

Target is that I'm in college learning all this, and we are to convert float to int without doing:

copyinput = (int) (input * 100 + 0.5).

Tutor says: If I'm doing that I would have to justify to him
why I'm using the precise (0.5) adition.

As the difference (input to next upper natural number) is not the same at all times I'd like to establish the precise difference between the inprecision and the next natural number. So that I can then add that inprecision to the number(input) to get the next natural number.

I hope I expressed this clearly and understandably.
6. you will have to break the float in the integer part and the decimal part. do the operations and add them together. i guess it is easier if you do this at the end of the float operations, right before the conversion to int. there are some functions for this like modf(). you will also have to decide how to round the integers.
7. No Profile Picture
Contributing User
Devshed Novice (500 - 999 posts)

Join Date
Jun 2003
Posts
705
Rep Power
15
Sometimes it takes clairvoyance to provide the answer a professor is insisting upon :p

I don't recognize the point he's trying to make about justification of the rounding, except the general concept of math proofs or "showing one's work on paper" in algebra or the calculus.

Anyway, floats have a tendency to loose precision, as you recognize. You can't always determine what the original intent for a particular number was supposed to be.

Take two floats, d1 and d2, set both equal to 10.1.

Now, d3 = d1 + d2;

d3 should be 20.2. The computer "thinks" it's 20.200001.

Now, do the same thing in doubles.

Should be 20.2 again, but the computer "thinks" is 20.199999999999999

Now, given d3 in either case, how could you guess what the number ought to be? You can't.

There is no choice but to round.

This applies to all operations, as you've observed with multiplication. There are values ( be it type double, float - whatever "real" type) which can rather accurately depict the original, but as you've observed this isn't consisitent.

There is no choice but to round, but how can be a valid question. Generally speaking, in order to pin down what the floating point value should "read" or "represent" you must decide on a level of precision. This is applicable beyond programming; virtually all scientific or related industrial calculations are pegged to a tolerance of some limit. It's the specification of that limit that gives you justification for rounding.

Conversion to an integer via multiplication by 100 gives you some authority to round to two decimal places (at least from a non-programming point of view). Lacking decimal places, though, integers don't lend themselves to rounding through addition by 0.5, and as you've observed that addition is, itself, possibly prone to an error.

Now, consider modf, as suggested, with the example values above. Using doubles, the modf result of "d3" is 20.00000, which we'll call d4. To get the fractional part, d5 = d3 - d4, which gives the maddening answer: 0.19999999999999929

Floats fare no better. While d4 provides the reassuring 20.0, d5 returns a frustrating: 0.20000076

Though, you'll recognize, for these particular values, floats would naturally truncate in your integer conversion (without .5 addition) to a "good" result. Other values, however, may not.

At this point I must chuckle at the futility.

BTW, in doubles, d3 = 8888.88 will cause any "print" or "use" of d3 to "think" it's 8888.8799999999992. Cute, eh? That's without ANY math operation upon d3!

In any case, your justification for rounding is clear. The value 0.5 is appropriate as part of a "5/4 rounding method" on paper, but there are exceptions. Consider 8888.845. A float stores this value as 8888.8447, will not round to two decimal places as you expect (it should become 888885 in your integer conversion, if everything were exact). It won't. It will become 888884.

Interestingly, even with a double, the value is represented at 8888.8449999999993, and so

int val = (int)( d3 * 100 +.5) results in 888884.

However, this:

int val = ((int)( d3 * 1000 + 5) / 10;

results in 888885!

So, what's a programmer to do?

Clairvoyance, I'm afraid.
Last edited by jasonvene; December 8th, 2004 at 03:18 PM.
8. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Nov 2004
Posts
6
Rep Power
0
Originally Posted by jasonvene
Sometimes it takes clairvoyance to provide the answer a professor is insisting upon :p

I don't recognize the point he's trying to make about justification of the rounding, except the general concept of math proofs or "showing one's work on paper" in algebra or the calculus.

So, what's a programmer to do?

Clairvoyance, I'm afraid.
Jasonvene,

Here it is your answer captures all that I needed to understand and need for the problem at hand:

' provide the answer a professor is insisting upon '

Well his point is I think that we need to understand the inprecision of floats and doubles as whole when programming a particular problem. I think it's a good exercise to get our head round this ourselves.

I thank all for their interesting and very helpfull contributions, especially you 'Jasonvene'.
Kind regards,

Silvanus

ps: had to study hard for some project thats why the late reply.
9. Maybe it's easier to understand the imprecision if you consider it in it's simplest terms. On my 32-bit machine an integer is 32 bits and so's a float (a double is 64). How does one get a zillion times the range with a float when the number of bits available to encode it is the same? Magic? Nope, loss of precision.
10. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Oct 2012
Posts
1
Rep Power
0

#### Percision Issue when converting from float to int : Thanks Jasonvene

Thanks Jasonvene.

I am just beginning to learn how to program in C with my son who is taking it in school. The teacher assigned a problem to figure out the domination of change (\$) received from a customer.

I was having an issue with myreturn_int loosing precision causing the end value to be a penny short when the change was \$x.y6 to \$x.y8.

float cash, sale, myreturn; \\ cash=\$10, sale=\$7.53
myreturn = cash - sale; \\ myreturn=\$2.47
myr = (myreturn * 100); \\ myr=246.9999
myreturn_int = myr; \\ myreturn_int=246

myr = (myreturn * 1000 + 5)/10; \\ myr=247.49
myreturn_int = myr; \\ myr=247

Now the program works great and I am never a penny short.

I could have just tried the rounding function but we have only learned up to chapter 4 of the "Programming in C" by Kochan book.

I'm glad I discovered this forum online. It's a great help for me.

Thanks Jasonvene for a wonderful explanation.
11. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Feb 2004
Posts
20
Rep Power
0
Originally Posted by Silvanus
Target is that I'm in college learning all this, and we are to convert float to int without doing:

copyinput = (int) (input * 100 + 0.5).

Tutor says: If I'm doing that I would have to justify to him
why I'm using the precise (0.5) adition.
IMO, in order to correctly convert the float to int, you need to round using .5 -- so what's wrong with justifying it? If he said that, maybe he wants you to think about it and explain why this is a good way to do it.

Just because you are asked to justify something does not mean it's wrong. It means you understand why it's necessary.