Reputation: 279
It is hard to explain the question, i would like to convert a double number to integer without rounding the value after the decimal point. For example
double a = 123.456
I want to convert become
int b = 123456
I want to know how many digit there is, and move it back after calculated to become 123.456
PS:I just want pure mathematical method to solve this issue, without calculating the character of it.
Upvotes: 0
Views: 339
Reputation: 215259
Sorry, there's no solution to your problem because the number 123.456 does not exist as a double. It's rounded to 123.4560000000000030695446184836328029632568359375, and this number obviously does not fit into any integer type after you remove the decimal point.
If you want 123.456 to be treated as the exact number 123.456, then the only remotely simple way to do this is to convert it to a string and remove the decimal point from the string. This can be achieved with something like
snprintf(buf, sizeof buf, "%.13f", 123.456);
Actually figuring out the number of places you want to print it to, however, is rather difficult. If you use too many, you'll end up picking up part of the exact value I showed above. If you use too few, then obviously you'll drop places you wanted to keep.
Upvotes: 12
Reputation: 76305
If you have the text "123.456"
you can simply remove the decimal point and convert the resulting text representation to an integer value. If you have already converted the text to a floating-point value (double a = 123.456;
) then all bets are off: the floating-point value does not have a pre-set number of decimal digits, because it is represented as a binary fraction. It's sort of like 1/3 versus .3333 in ordinary usage: they do not have the same value, even though we usually pretend that .3333 means 1/3.
Upvotes: 0
Reputation: 213842
I believe the canonical way to do this would be
#include <math.h>
#include <stdio.h>
int main()
{
double d = 123.456;
double int_part;
double fract_part;
fract_part = modf(d, &int_part);
int i = (int)int_part*1000 + (int)(fract_part*1000);
printf("%d", i);
}
where the literal 1000 is a constant determining the number of desired decimals.
Upvotes: 0
Reputation: 9
try this :
double a = 123.456;
int i;
char str[20];
char str2[20];
sptrintf(str,"%d",a);
for(i=0;i<strlen(str);i++)
{
if(!str[i] == '.')
{
sptrintf(str2,%c,str[i]);
}
}
int b = atoi(str2);
Upvotes: 0
Reputation: 92
Multiply each time original value with 10^i, increasing each time i until abs(value' - abs(value')) < epsilon for a very small epsilon. value' should be computed from the original each time, e.g.
value' = value * pow(10, i)
if ( abs(value' - abs(value')) < epsilon ) then stop
Originally I suggested that you should simply multiply by ten, but as R.. suggested, each time the numerical error gets accumulated. As result you might get a result of e.g. 123.456999 for an epsilon = .0000001 instead of 123.456000 due to floating point math.
Please note that you might exceed int type boundaries this way and might want to handle infinity values as well.
As Ignacio Vazquez-Abrams noted this might lead to problems with scenarios where you want to convert 123.500 to 123500. You might solve it by adding a very small value first (and it should be smaller than epsilon). Adding such a value could lead to a numeric error though.
Upvotes: -1