Click here to Skip to main content
15,893,588 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,
i am writing in native C, using visual studio 2010 the following code:

C++
float temp = 0;
int temp2 = 0
printf("Enter decimal number between 30.00 to 1000.00\n");
scanf("%f", &temp);
temp2 = (int)(temp*100);



the problem is that i loose percision when i try to cast the number into
an integer.

for example if user enters 30.15
temp2 gets the value 3014;

how can i overcome this issue ?!
Posted
Updated 6-Dec-10 11:22am
v2

I actually tried it in C#, but I think the math lib is the same.
C#
string s = "30.15";
float f = float.Parse(s);
int i = (int) (f * 100);
float g = f * 100;
int j = (int) (g);
MessageBox.Show(i.ToString() + ":" + j.ToString());
Gives the message box
3014:3015
Which is a little odd, but means that it may be worth your trying to create a local float yourself...
 
Share this answer
 
It's not loosing precision, it never had it in the first place. If you work out what the binary representation of 30.15 you'll find out that it's represented as something a bit less than 30.15 for the number of bits you've got in a float. In fact as 0.15 is not a fraction that can be represented by summing successive powers of 0.5 you'll never get get the sort of precision you're after.

So what can you do about it?

Well one thing you could do is use a data type that doesn't loose precision, e.g. a pair of ints. So you'd read in using something like:

int whole_part = 0;
int hundredths = 0;

scanf( "%d.%d", &whole_part, &hundredths );

int temp = whole_part * 100 + hundredths;


Basically the moral is floating point numbers in the real world are approximations (e.g. when you write 30.15 you're actually saying "a number in the half open range 30.145 to 30.155") and computers are no different. So don't use them when you need a lot of precision, use fixed point numbers where you can or at least know how they work so you can fix problems when they happen.

Cheers,

Ash

PS: Remember to check the return value of scanf and you'll want to declare temp at the start of a block, not after carrying out some other statements the way I have.
 
Share this answer
 
v2
The cast does not round. It only cuts away the numbers.
Simple add 0.5 before casting.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900