我试图在 C 中考虑一个满足以下条件的函数:
- 它接受大于 0 的整数作为参数;
- 它将整数向上舍入到最接近的值,以便只有第一个数字不是零
例如:
53出来是60..
197出来是200..
4937 出来是 5000..
有没有办法做到这一点,无论尾随零的数量如何都能满足要求?
例如,我了解如何在任何个别情况下做到这一点。divide 53 by 10 then ceil(), multiply by 10,
但我想要一个可以处理任何价值的人。
意见?想法?
避免字符串转换和循环:
int num = ... // your number
int len = log10(num);
float div = pow(10, len);
int rounded = ceil(num / div) * div;
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));
对数在这里非常有用,可以为“这有多少个零?”提供恒定时间的答案。
floor(log10(x))= z //the number of zeros
将取对数以 10 为底,并给出 x 中零的数量。
然后你可以使用 C 偶尔的成语
(A+B-1)/B
快速找到 A/B 的上限,从而以这种方式得出正确的前导数字:
zeros = exp10(1,z);
((x+zeros-1)/zeros) * zeros
这是伪代码,但你应该明白。关键的理解是对数是数学上确定一个数字有多少位数的方法。
我不确定你想要圆形还是天花板。但是您在问题中表现出的行为暗示了 ceil。所以我把它包括在内。
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;
}
编辑
更改了代码以删除 ceil 和其他额外操作。
编辑 2
固定为 10 的倍数。
通过 Cocoa API:
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);
通过典型的 C 风格,数学上:
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);
这应该这样做:
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);
}
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.
我会将数字转换为字符串。获取字符串的长度。
然后:
// pseudo code:
divisor = pow(10, len of number string)
answer = ceil (number/divisor) * divisor;
没有循环。
#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 ;
}
您可以将数字除以十,直到只剩下一位数字,然后将其乘回大小:
int n = 4937;
int m = 1;
while (n >= 10) {
n = (n + 9) / 10;
m *= 10;
}
n *= m;
/*-------------------------------------------------*/
/* 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
*/
你在这里得到的一些专家建议......将一个数字四舍五入到最接近的 10:
if (i%10)
i += 10 - i%10;
同样对于 100s、1000s 等。