Rounding integers to nearest ten or hundred in C
Solution 1
Avoid string conversions and loops:
int num = ... // your number
int len = log10(num);
float div = pow(10, len);
int rounded = ceil(num / div) * div;
Solution 2
Logarithms are quite helpful here to provide a constant-time answer to the "how many zeros does this have?"
floor(log10(x))= z //the number of zeros
will take the logarithm base 10 and give you the number of zeros that will be in x.
You can then use the C occasional idiom
(A+B-1)/B
to quickly find the ceiling of A/B, which results in the correct leading digit in this way:
zeros = exp10(1,z);
((x+zeros-1)/zeros) * zeros
This is pseudocode but you should get the idea. The key understanding is that logarithms are the way to mathematically determine how many digits a number has.
Solution 3
By Cocoa APIs:
int number=9435;
NSString *string=[NSString stringWithFormat:@"%d",number];
long length=[string length];
NSString *roundedString=[NSString stringWithFormat:@"%d",([[string substringToIndex:1]intValue]+1)];
while (--length>0) {
roundedString=[roundedString stringByAppendingString:@"0"];
}
int roundedNumber=[roundedString intValue];
NSLog(@"%d, %d",number,roundedNumber);
By Typical C style, mathematically:
int i=8517;
int temp=i;
int len,msb;
for (len=0; temp>0; len++) {
msb=temp;
temp/=10;
}
msb++;
int multiplier=1;
for (int i=1; i<len; i++) {
multiplier*=10;
}
NSLog(@"Rounded : %d",msb*multiplier);
Solution 4
I am not sure if you want round or ceil. But the behavior you show in the question suggests ceil. So I included that.
int my_ceil(int num)
{
int den = 1;
int inc = 0;
while (num >= 10) {
inc += num % 10;
num /= 10;
den *= 10;
}
return (num + (inc > 0)) * den;
}
EDIT
Changed the code to remove ceil and other extra operations.
EDIT 2
Fixed for multiples of 10.
Comments
-
M. Ryan almost 2 years
I'm trying to think of a function in C that would satisfy the following conditions:
- It accepts an integer greater than 0 as an argument;
- It rounds that integer up to the nearest value so that only the first digit is not a zero
For example:
53 comes out as 60..
197 comes out as 200..
4937 comes out as 5000..
Is there a way to do this so that the requirement is satisfied regardless of the number of trailing zeroes?
For example, I understand how I could do it in any individual case.
divide 53 by 10 then ceil(), multiply by 10,
but I would like one that can handle any value.Opinions? Ideas?
-
Ramy Al Zuhouri over 11 yearsThe syntax isn't ok but it expresses the concept. +1.
-
rmaddy over 11 yearsThis is tagged a C, not VB.
-
Brian Salta over 11 yearsHence why I wrote "In VB, but hopefully you get the idea." The concept still applies.
-
Anoop Vaidya over 11 yearsI saw dozens of answers, and even I can solve this junior level school problem, I got eager to solve this... howver using few cocoa API this could be solved much easily.... :D
-
Guffa over 11 yearsDoesn't work for some numbers. If the number is 9, the result is 10, if the number is 10, the result is 11...
-
Pavan Yalamanchili over 11 years@Guffa You are right, it wouldn't work for any multiples of 10. I think I fixed now.
-
Clifford over 11 yearsMathematically the number of decimal digits is
floor(log10(n) + 1))
or more simply(int)(log10(m) + 1)
- no need for string conversion. -
Clifford over 11 yearsMay be worth noting that
exp10(n)
is a GNU library extension equivalent topow(10,n)
-
Anoop Vaidya over 11 yearsIts tooo late, but added one more way using cocoa strings
-
Pavan Yalamanchili over 11 years@Guffa It was producing 10 not 180. Missed the parenthesis.
-
Clifford over 11 years
trunc()
andround()
are not standard either -
Clifford over 11 yearsWorks but needs C99 or C++ compilation due to placement of declarations.
-
Clifford over 11 yearsI don't think that is a good advert for Cocoa or Objective-C ;-) Unreadable. And the question is tagged C.
-
Pavan Yalamanchili over 11 years@Clifford old habits :). Taking out the if condition should fix things. It is not strictly necessary.
-
Clifford over 11 yearsIf the input were 200, the output will be 300 when it should be 200.
-
Clifford over 11 years@Pavan: The code was fine, I was just making a note for anyone using C compilation in Visual C++.
-
Pavan Yalamanchili over 11 years@Clifford Thanks for pointing out anyway. I was able to remove an additional line of code because I looked back at it.
-
Lee-Man over 11 yearsCompiled on standard linux using _GNU_SOURCE and math.h. I did not see a request to solve the problem with any particular subset of that.
-
Anoop Vaidya over 11 years@Clifford: He has edited the question, erlier it was tagged ios, cocoa, obj-c.
-
Clifford over 11 years@AnoopVaidya: My apologies.
-
Clifford over 11 yearsIndeed, I just made the point for anyone to whom it is important. In this case I tested many of the more rational looking solutions posted, but yours I could not test with VC++. I would take the lack of a target specification as implying a need for the widest possible widest possible applicability rather than a mandate to narrow the solution.
-
Lee-Man over 11 yearsMy goal was not to solve the actual problem of compiling the code, which is why I did not supply the whole program, though I had one. My goal was to show that the math is rather simple, and that it could be done for example on a standard Linux system.
-
Brad Werth over 9 yearsThis does not appear to satisfy the conditions put forth in the OP - "Is there a way to do this so that the requirement is satisfied regardless of the number of trailing zeroes?"