截断在c ++或通用示例中留下的整数

时间:2013-04-23 11:24:35

标签: c++ c algorithm

是否有一种方法可以在左方向十进制或基本独立中截断整数?

例如我有:

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;
}

谢谢!

7 个答案:

答案 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);
}