Rounding integers to nearest ten or hundred in C

24,006

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.

Share:
24,006
M. Ryan
Author by

M. Ryan

Objective-C, and other things when I am forced to

Updated on July 09, 2022

Comments

  • M. Ryan
    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
    Ramy Al Zuhouri over 11 years
    The syntax isn't ok but it expresses the concept. +1.
  • rmaddy
    rmaddy over 11 years
    This is tagged a C, not VB.
  • Brian Salta
    Brian Salta over 11 years
    Hence why I wrote "In VB, but hopefully you get the idea." The concept still applies.
  • Anoop Vaidya
    Anoop Vaidya over 11 years
    I 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
    Guffa over 11 years
    Doesn'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
    Pavan Yalamanchili over 11 years
    @Guffa You are right, it wouldn't work for any multiples of 10. I think I fixed now.
  • Clifford
    Clifford over 11 years
    Mathematically the number of decimal digits is floor(log10(n) + 1)) or more simply (int)(log10(m) + 1) - no need for string conversion.
  • Clifford
    Clifford over 11 years
    May be worth noting that exp10(n) is a GNU library extension equivalent to pow(10,n)
  • Anoop Vaidya
    Anoop Vaidya over 11 years
    Its tooo late, but added one more way using cocoa strings
  • Pavan Yalamanchili
    Pavan Yalamanchili over 11 years
    @Guffa It was producing 10 not 180. Missed the parenthesis.
  • Clifford
    Clifford over 11 years
    trunc() and round() are not standard either
  • Clifford
    Clifford over 11 years
    Works but needs C99 or C++ compilation due to placement of declarations.
  • Clifford
    Clifford over 11 years
    I don't think that is a good advert for Cocoa or Objective-C ;-) Unreadable. And the question is tagged C.
  • Pavan Yalamanchili
    Pavan Yalamanchili over 11 years
    @Clifford old habits :). Taking out the if condition should fix things. It is not strictly necessary.
  • Clifford
    Clifford over 11 years
    If the input were 200, the output will be 300 when it should be 200.
  • Clifford
    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
    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
    Lee-Man over 11 years
    Compiled 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
    Anoop Vaidya over 11 years
    @Clifford: He has edited the question, erlier it was tagged ios, cocoa, obj-c.
  • Clifford
    Clifford over 11 years
    @AnoopVaidya: My apologies.
  • Clifford
    Clifford over 11 years
    Indeed, 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
    Lee-Man over 11 years
    My 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
    Brad Werth over 9 years
    This 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?"