Reputation: 7192
I'm trying to think of a function in C that would satisfy the following conditions:
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?
Upvotes: 9
Views: 31337
Reputation: 1
Some expert advice you get here... To round a number i up to nearest 10:
if (i%10)
i += 10 - i%10;
Similarly for 100s, 1000s, etc.
Upvotes: -3
Reputation: 1
/*-------------------------------------------------*/
/* Round up a number */
/* (Negative numbers go DOWN) */
/* 34 -> 40 */
/* -34 -> -40 */
/*-------------------------------------------------*/
int round_up_10(int num)
{
int sign = 1;
int tens = 1;
if (num < 0)
{
num = (-1) * num;
sign = -1;
}
num = (num + 9) / 10;
num = num * 10;
return sign * num;
}
/*-------------------------------------------------*/
/* Round down a number */
/* (Negative numbers go UP) */
/* 34 -> 30 */
/* -34 -> -30 */
/*-------------------------------------------------*/
int round_down_10(int num)
{
int sign = 1;
int tens = 1;
if (num < 0)
{
num = (-1) * num;
sign = -1;
}
num = num / 10;
num = num * 10;
return sign * num;
}
main()
{
printf("round_down_10(25450)= %d\n", round_down_10(25450));
printf("round_down_10(-25450)= %d\n", round_down_10(-25450));
printf("round_up_10(25450)= %d\n", round_up_10(25450));
printf("round_up_10(-25450)= %d\n", round_up_10(-25450));
printf("round_down_10(1347)= %d\n", round_down_10(1347));
printf("round_down_10(-1347)= %d\n", round_down_10(-1347));
printf("round_up_10(1347)= %d\n", round_up_10(1347));
printf("round_up_10(-1347)= %d\n", round_up_10(-1347));
printf("round_down_10(34)= %d\n", round_down_10(34));
printf("round_down_10(-34)= %d\n", round_down_10(-34));
printf("round_up_10(34)= %d\n", round_up_10(34));
printf("round_up_10(-34)= %d\n", round_up_10(-34));
}
/*
The outout:
round_down_10(25450)= 25450
round_down_10(-25450)= -25450
round_up_10(25450)= 25450
round_up_10(-25450)= -25450
round_down_10(1347)= 1340
round_down_10(-1347)= -1340
round_up_10(1347)= 1350
round_up_10(-1347)= -1350
round_down_10(34)= 30
round_down_10(-34)= -30
round_up_10(34)= 40
round_up_10(-34)= -40
*/
Upvotes: 0
Reputation:
It's unnecessary to convert the number to a string and back. You can do this using basic modulo arithmetic and multiplication and division.
Here's a pure numeric solution, hopefully somewhat more efficient in terms of running time:
int round_up_to_max_pow10(int n)
{
int tmp = n;
int i = 0;
while ((tmp /= 10) >= 10) {
i++;
}
if (n % (int)(pow(10, i + 1) + 0.5)) {
tmp++;
}
for (; i >= 0; i--) {
tmp *= 10;
}
return tmp;
}
printf("Original: %d; rounded: %d\n", 4937, round_up_to_max_pow10(4937));
Upvotes: 10
Reputation: 93476
No loops.
#include <math.h>
unsigned roundToNextExp10( unsigned a )
{
int d = a ;
if( a >= 10 )
{
int m ;
d-- ;
m = (int)pow( 10, ((int)log10(d)) ) ;
d = (int)((d / m) + 1) * m ;
}
return d ;
}
Upvotes: 0
Reputation: 12099
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.
Upvotes: 1
Reputation: 46543
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);
Upvotes: 1
Reputation: 414
This should do it:
static int
rnd_up(int val)
{
double e, r;
e = exp10(trunc(log10((double)val)));
r = round(((double)val / e) + 0.5);
return(r * e);
}
Upvotes: 0
Reputation: 700372
You can divide the number by ten until there is only one digit left, then multiply it back to size:
int n = 4937;
int m = 1;
while (n >= 10) {
n = (n + 9) / 10;
m *= 10;
}
n *= m;
Upvotes: 0
Reputation: 721
I would convert the number to string. Get the length of the string.
Then:
// pseudo code:
divisor = pow(10, len of number string)
answer = ceil (number/divisor) * divisor;
Upvotes: 0
Reputation: 318824
Avoid string conversions and loops:
int num = ... // your number
int len = log10(num);
float div = pow(10, len);
int rounded = ceil(num / div) * div;
Upvotes: 20
Reputation: 2778
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.
Upvotes: 3
Reputation: 1576
Try taking the first character of the input number, add 1, then append zeros.
Dim Input = "23568"
Dim roundUp = Left(Input, 1) + 1
For x = 1 To Len(Input) - 1
roundUp &= "0"
Next
In VB, but hopefully you get the idea.
Upvotes: 0