C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old December 7th, 2004, 09:20 PM
Silvanus Silvanus is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Posts: 6 Silvanus User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 36 m 26 sec
Reputation 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.

Reply With Quote
  #2  
Old December 7th, 2004, 10:19 PM
L7Sqr L7Sqr is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jan 2004
Location: Constant Limbo
Posts: 989 L7Sqr User rank is Major (30000 - 40000 Reputation Level)L7Sqr User rank is Major (30000 - 40000 Reputation Level)L7Sqr User rank is Major (30000 - 40000 Reputation Level)L7Sqr User rank is Major (30000 - 40000 Reputation Level)L7Sqr User rank is Major (30000 - 40000 Reputation Level)L7Sqr User rank is Major (30000 - 40000 Reputation Level)L7Sqr User rank is Major (30000 - 40000 Reputation Level)L7Sqr User rank is Major (30000 - 40000 Reputation Level)L7Sqr User rank is Major (30000 - 40000 Reputation Level)L7Sqr User rank is Major (30000 - 40000 Reputation Level) 
Time spent in forums: 2 Weeks 2 Days 22 h 45 m 6 sec
Reputation Power: 362
Send a message via AIM to L7Sqr
why not just leave it as a float?
__________________
True happiness is not getting what you want, it's wanting what you've already got.

My Blog

Reply With Quote
  #3  
Old December 7th, 2004, 10:44 PM
jasonvene jasonvene is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jun 2003
Posts: 705 jasonvene User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 7 m 27 sec
Reputation Power: 10
floats and float math is inherently imprecise.

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

What is your target, though?

Reply With Quote
  #4  
Old December 8th, 2004, 01:28 AM
The Dark The Dark is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: May 2004
Location: Adelaide, Australia
Posts: 880 The Dark User rank is Lance Corporal (50 - 100 Reputation Level)The Dark User rank is Lance Corporal (50 - 100 Reputation Level)The Dark User rank is Lance Corporal (50 - 100 Reputation Level) 
Time spent in forums: 1 Day 14 h 15 m 25 sec
Reputation Power: 10
You could always do
copyinput = (int) (input * 100 + 0.5);

which will round off, rather than down.

Reply With Quote
  #5  
Old December 8th, 2004, 07:09 AM
Silvanus Silvanus is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Posts: 6 Silvanus User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 36 m 26 sec
Reputation Power: 0
Quote:
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.

What is your target, though?


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.

Reply With Quote
  #6  
Old December 8th, 2004, 09:48 AM
arpia's Avatar
arpia arpia is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jun 2003
Location: Baltimore, MD
Posts: 229 arpia User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 13 m 58 sec
Reputation Power: 10
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.

Reply With Quote
  #7  
Old December 8th, 2004, 02:11 PM
jasonvene jasonvene is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jun 2003
Posts: 705 jasonvene User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 7 m 27 sec
Reputation Power: 10
Sometimes it takes clairvoyance to provide the answer a professor is insisting upon

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 02:18 PM.

Reply With Quote
  #8  
Old December 10th, 2004, 04:19 PM
Silvanus Silvanus is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Posts: 6 Silvanus User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 36 m 26 sec
Reputation Power: 0
Quote:
Originally Posted by jasonvene
Sometimes it takes clairvoyance to provide the answer a professor is insisting upon

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.

Reply With Quote
  #9  
Old December 10th, 2004, 04:33 PM
DaWei_M's Avatar
DaWei_M DaWei_M is offline
Renaissance Redneck
Dev Shed God 8th Plane (8500 - 8999 posts)
 
Join Date: Jan 2004
Location: Central New York. Texan via Arizona, out of his element!
Posts: 8,511 DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level)DaWei_M User rank is General 34th Grade (Above 100000 Reputation Level) 
Time spent in forums: 4 Weeks 18 h 26 m 26 sec
Warnings Level: 20
Number of bans: 3
Reputation Power: 3268
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.
__________________
Functionality rules and clarity matters; if you can work a little elegance in there, you're stylin'.
If you can't spell "u", "ur", and "ne1", why would I hire you? 300 baud modem? Forget I mentioned it.
DaWei on Pointers Politically Incorrect.

Reply With Quote
  #10  
Old October 8th, 2012, 07:51 PM
morrbie morrbie is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2012
Posts: 1 morrbie User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 10 m 38 sec
Reputation 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

BUT after reading your answer/suggestion, I tried:
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.

Reply With Quote
  #11  
Old October 9th, 2012, 01:30 AM
WaltP WaltP is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Feb 2004
Posts: 19 WaltP User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 26 m 27 sec
Reputation Power: 0
Quote:
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.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > loss of precision float to int in c

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap