Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
Solved

# Pls help.. inconsistent integer conversion

Posted on 1998-09-20
Medium Priority
293 Views
Hi guys,
I am out of points so pls. try to help ;)
I have a double which I want to typecast to an int
ie. = double ret ;
int i;
ret = ..... some calculation (using floor/ceil/pow);
i = (int) ret;

Then problem is that I printed out both ret and i:
ret = 510 BUT i = 509  !!!!!!! inconsistent
why is the convesion inconsistent and HOW do i solve it?
I tried typecaseting it to a long int but it is still the same....
Pls. help.. thanks!!!

David

0
Question by:Haho
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 6
• 6
• 2
• +1

LVL 1

Expert Comment

ID: 1252910
#include <stdio.h>
int main(void)
{
float r;
int i;
r = 509.9;
i = r;
printf("%5.0f\n", r);
printf("%7.1f\n", r);
printf("%5d\n", i);
return 0;
}
when executed produces
510
509.9
509
In other words the "i = r;" truncates, but the "printf("%5.0f\n", r);" rounds.
Is this clear?
0

Accepted Solution

gbeau earned 0 total points
ID: 1252911
The problem is that the conversion rounds down (as warren_dale implies).  If you really do want to round a floating point number (float or double) to the *nearest* integer (int or long), just add 0.5 before you do the conversion, eg.

float number = 0.9999f;
int nearestInt = (int)(number + 0.5f);

0.9999 + 0.5 = 1.4999, which will get rounded down to 1 in the conversion.

0

LVL 1

Author Comment

ID: 1252912
yes, but my answer should be 510 , not 509
when I print it out as double , it reads 510.0
so by right, if I convert it to integer , it should also be 510 and not 509.
Pls. note that the 510 val is computed and not assigned.

0

LVL 1

Expert Comment

ID: 1252913
What is the actual value?
What source code do you use that prints out the value as 510?
0

LVL 84

Expert Comment

ID: 1252914
double r;
int i;
r = -1e-4;
r += 510;
i = r;
printf("%.20f\n", r);
printf("%.1f\n", r);
printf("%d\n", i);
0

LVL 1

Author Comment

ID: 1252915
actually I'm using a rounding function:
fround(n,d) ((floor((n) * pow(10.,(d))) / pow(10. ,(d)))
which is a rounding down function.

and I used it to calculate addition of 2 numbers, a + b
a = fround( value1, nodec);
b = fround (value2, nodec);
1)   result  =  a+ b;
after which I round the final answer ( i have a few rounding variations,
round adjust, round up, down,... )
2) result = fround ( result, nodec);

From 1) where a = b= 2.555 and nodec = 2, my answer after 1) is result = 5.10
(I printed it out as a double) BUT after 2) where it is rounded again,
it comes out as 509 ( I printed it again )..
u see my problem?? :)
So I wrote my own myfloor function which returns a double as a integer,
basically doing a rounding down by : return (int) doublevalue;
and I printed out both 3) doublevalue and 4) (int) doublevalue
by the same values entered , 3) = 510 and 4) gives me 509... again the same problem!!!

Hope that explains how I got the problem.. thanks guys and keep those comments coming in..!!!

David

0

LVL 84

Expert Comment

ID: 1252916
#include <stdio.h>
#include <math.h>
int main(void){
double r;
int i;
r = 255.0/100.0 + 255.0/100.0;
i = r;
printf("%.20f\n", r);
printf("%.1f\n", r);
printf("%d\n", i);
r *= 100;
i = r;
printf("%.20f\n", r);
printf("%.2f\n", r);
printf("%d\n", i);
return 0;
}
when executed produces
5.09999999999999960000
5.10
5
509.99999999999994000000
510.00
509

0

LVL 1

Author Comment

ID: 1252917
to ozo: thanks!!!
so it basically boils down to the fact that double does some rounding up (depending on the decimal val) while integer just truncates it..  : )
I guess that gbeau (thanks) answer should solve this problem ie. (int)(value + 0.5)
what do u think?? Is it a good solution to this problem or is there another way?
I remember a similar prob in MFC and I used _fcvt to work round it..  ;) But then, this is Unix.
0

LVL 84

Expert Comment

ID: 1252918
printf %f does rounding.
(int) just truncates
(double) is only approximate

(int)(value + 0.5)
only works if value > -0.5
0

LVL 1

Author Comment

ID: 1252919
what bout negative values then??
check the if condition and do (int)(val - 0.5)?
Until now, there has been no clear solution to my problem...
:( I know the why but I am still looking for the how..
anyway, the solution must be reliable ..
0

LVL 84

Expert Comment

ID: 1252920
> check the if condition and do (int)(val - 0.5)?
That can be ok if val is int he range of an int.
floor(val+0.5) may be a better choice in general.
(although you may prefer a true round-to-even if you;re woring with decimal representations)
or if you need more precise control over exact values, you may even want to to all your calculations using int
0

LVL 1

Author Comment

ID: 1252921
that comes back to round one...
my rounding down (or up) for FP function is:
rounddown = floor( FPvalue * pow(10,dec) )/(pow(10,dec))
by doing the above:
floor( val + 0.5) ; it is not a rounding down func anymore..
it is a normal rounding adjust func which is not what I need ..
by doing the above ...
:)

0

LVL 84

Expert Comment

ID: 1252922
No matter what you do, there will always exist values which are not exactly represetable as a (double)
255.0/100.0 is one such value
and any code which depends on 255.0/100.0 being exactly represented in a (double) is faulty
If you don't need to distinguish numbers between, say 254999.0/100000.0 and 255001.0/100000.0
then you may be able write your code in a way that treats all numbers in that range the same.
If you don't mind your rounddown value only being accurate within  1/(pow(10,dec), you might use something like
(floor( FPvalue * pow(10,dec))+0.1 )/(pow(10,dec))
and be able to repeatedly apply the function without accumulating additional error.
But if you need be able to distingush, say
254999999999999999/100000000000000000 from 255000000000000001/100000000000000000
then you may not be able to do it in a (double)
If so, perhaps your needs may be better served with some sort of extended precision data type.
Or if you know you always want all your values exact to two decimal places,
then instead of dealing with (double)5.10 which is not exact,
you might instead always deal internally with (int)510 which is exact.
0

LVL 1

Author Comment

ID: 1252923
Yes, I really need be able to distingush
254999999999999999/100000000000000000 from
255000000000000001/100000000000000000
and the fact that my decimal representation is not fixed means that there really is
no perfect solution to my prob. :(
Extended precision data type? Maybe but I have no idea how. Perhpas a hint?? ;)
Ozo .. thank u for explaining all that to me and I think u really deserve a lot more points than zero.. :)
Tell u what, give a dummy answer to another question that I have (150 points) that so far so one has answered well and I will give those 150 points to u that u deserve for helping me here...  cause the other question is not needed by me now.
Thanks again and feel free to post any more comments on this....

Ps. right now I am trying out a string rounding function that seems to work well ( exact anyway ).. it may be slow and inefficient but at least I know that the result are always consistent cause I am using the nos for financial calculations....

David

0

LVL 84

Expert Comment

ID: 1252924
> Yes, I really need be able to distingush
>           254999999999999999/100000000000000000 from
>           255000000000000001/100000000000000000
So you need at least 18 digits worth of precision,
Do you know how much precision will be required in all?

If you don't want to write your own multiple precision routines,
you might try using GNU MP library, or, if you're on a unix system, you may be able to just fork a `dc` process to do the arithmetic.
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to useâ€¦
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see soâ€¦
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
###### Suggested Courses
Course of the Month10 days, 14 hours left to enroll