是否有一种方法可以在左方向十进制或基本独立中截断整数?
例如我有:
unsigned int val1 = 17301;
算法必须通过一次调用从左侧截断1(十进制)数字,因此对于val1,4次调用的结果将是:
truncate_left(17301) returns 7301
truncate_left(7301) returns 301
truncate_left(301) returns 1
truncate_left(1) returns 0
返回值也是整数。 c / c ++解决方案对我来说是最好的。任何外部(和/或)数学库都不受欢迎,我对通用方法感兴趣
@ATaylor 我丑陋的解决方案是:
unsigned int truncate_left(unsigned int val) {
unsigned int divider = 1000000000, dec;
for(unsigned int pow10 = 10; pow10 > 0; pow10--) {
if(val % divider != val) {
dec = val / divider;
printf("dec = %d\n", divider);
break;
}
divider /= 10;
}
return val - dec * divider;
}
谢谢!
答案 0 :(得分:4)
我不确定为什么@MM删除了他的差不多答案,但这里是纠正后的版本:
int truncate_left(int x)
{
int c = (int)log10(x);
while (x > pow(10,c)) x -= pow(10,c);
return x;
}
如果使用math.h和-lm是个问题,请将log10和pow替换为:
int mylog10(int val)
{
if (val > 9) return 1 + mylog10(val/10);
return 1;
}
int mypow(int val, int pwr)
{
if (pwr > 0) return val * mypow(val, pwr-1);
return val;
}
答案 1 :(得分:3)
这是一个解决方法,但它应该做你想要的(虽然我不明白为什么你想要它)
无论如何,首先,你需要确定哪个数字是最左边的数字。
为此,你需要知道基础(你知道吗,对吧?) 一旦你知道了最左边的数字,你就需要将这个确切的数字减去基数的位置倍数......然后你就完成了。
这是一个关于如何完成此操作的代码片段。虽然未经测试。
int truncate_left(int val, int base) {
int Multiplier = 1, LeftDigit = val;
while(LeftDigit > base) {
LeftDigit /= base;
Multiplier *= base;
}
return val - (LeftDigit * Multiplier);
}
为了处理负数,我们还需要额外添加一些。
int truncate_left(int val, int base) {
bool isNegative = (val < 0);
int Multiplier = 1, LeftDigit = val;
if(isNegative) LeftDigit *= -1;
while(LeftDigit > base) {
LeftDigit /= base;
Multiplier *= base;
}
if(isNegative) LeftDigit *= -1;
return val - (LeftDigit * Multiplier);
}
isNegative
标志会记住,如果数字为开头是负数并且为方便起见而存在(我们也可以两次检查val < 0
)。它将LeftDigit
变为正数(它的'绝对值',确定乘数,然后将其变回负值。
由于val
是否定的,我们从中减去另一个负值(-LeftDigit *乘数),它等于+
,导致保留符号的正确结果。
答案 2 :(得分:3)
如果字符串不作弊:
int truncate_left(int i) {
return std::stoi(std::to_string(i).substr(1));
}
答案 3 :(得分:2)
我刚刚写了:
int truncate_left(int x)
{
int c = (int)log10(x); // c: digits - 1
int p = pow(10,c); // p: 10 ^ c
int k = x / p; // k: leftmost non-zero digit
return x - k * p;
}
注意:x
应大于零。
答案 4 :(得分:2)
没有快捷的方法。您必须将17301写为10000 + 7301.很明显truncate_left返回7301部分。这样就可以找出10000部分,你可以从“打印数字”代码示例中找出它。
答案 5 :(得分:1)
也检查一下,
unsigned int tru(unsigned int a)
{
unsigned int b = a,c=0;
while(b!=0)
{
c++;
b /=10;
}
cout<<"length: "<<c<<endl;
int mul= 1;
c--;
while(c)
{
mul *= 10;
c--;
}
cout<<"mul is "<<mul<<endl;
return a%mul;
}
答案 6 :(得分:1)
unsigned truncate_left_aux(unsigned n, unsigned sum, unsigned base){
unsigned nn;
return (0==(nn=n/10))? sum : truncate_left_aux(nn, sum + (n % 10) * base, 10*base);
}
unsigned truncate_left(unsigned n){
truncate_left_aux(n, 0, 1);
}