views:

475

answers:

8

If I have a number like 12345, and I want an output of 2345, is there a mathematical algorithm that does this? The hack in me wants to convert the number to a string, and substring it. I know this will work, but I'm sure there has to be a better way, and Google is failing me.

Likewise, for 12345, if I want 1234, is there another algorithm that will do that? The best I can come up with is Floor(x / 10^(n)), where x is the input and n is the number of digits to strip, but I feel like there has to be a better way, and I just can't see it.

+8  A: 

In the first case, don't you just want

n % 10000

i.e. the modulus wrt. 10000 ?

For your second case, if you're using integer arithmetic, just divide by 10. You might want to do this in a more 'explicit' fashion by modding with 10 to get the last digit, subtract and then divide (think of a shift in base 10).

Brian Agnew
+1: 12345 % 10000 = 2345
Chalkey
Very easy solution, beware thou, if it is performance one wants mod isn't the fastest way, but is way easier (but this also depends on the lang used)
Milan
+1  A: 

I don't think there's any other approach than division for removing trailing numbers. It might be more efficient to do repeated integral division than to cast to a float, perform an exponent, then floor and cast back to an integer, but the basic idea remains the same.

Keep in mind that the operation is nearly identical for any base. To remove one trailing decimal digit, you do / 10. If you had 0b0111 and you wanted to remove one digit, it would have to be /2. Or you could have 0xff / 16 to get 0x0f.

Mark Rushakoff
A: 

i think that converting to string and then remove the first char wont do the trick. i believe that the alg for converting to string is doing the div-mod routine, for optimization you might as well do the div-mod alg by yourself and manipulate it to your needs

+3  A: 

Yes, the modulus operator (%) which is present in most languages, can return the n last digits:

12345 % 10^4 = 12345 % 10000 = 2345

Integral division (/ in C/C++/Java) can return the first n digits:

12345 / 10^4 = 12345 / 10000 = 1

Avi
A: 

Here is C++ code ... It's not tested.

int myPow ( int n , int k ){
int ret = 1;
for (int i=0;i<k;++i) ret*=n;
return ret;
}

int countDigits (int n ){
 int count = 0;
 while ( n )++count, n/=10;
return count;
}

int getLastDigits (int number , int numDigits ){
  int tmp = myPow ( 10 , numDigits );
  return number % tmp;
}

int getFirstDigits (int number, numDigits ){
   int tmp = myPow ( 10, countDigits ( number) - numDigits );
   return nuber / tmp;
}
dpetek
+1  A: 

Converting to a string, and then using a substring method will ultimately be the fastest and best way, since you can just strip characters instead of doing math.

If you really don't want to do that though, you should use modulus (%), which gives the remainder of a division. 11 % 3 = 2, because 3 can only go into 11 three times (9). The remainder is then 2. 41 % 10 = 1, because 10 can go into 41 four times (40). The remainder is then 1.

For stripping the first digits, all you would have to do is mod the tens value that you want to get rid of. For stripping two digits from 12345, you should modulus by 1000. 1000 goes into 12345 twelve times, then the remainder will be 345, which is your answer. You would just need to find a way to find the tens value of the last digit you were trying to strip. Use x % (10^(n)), where x is input, and n is the lowest digit you want to strip.

For stripping the last digits, your way works just fine. What's easier than a quick formula like that?

Ethan
How will the integer be converted to a string, if not by "doing math"?
Steve Jessop
because the math is already built in with the string conversion methods?
Ethan
Just occurred to me that you were probably saying "fastest to write the code", not "fastest to run" as I assumed. And by "doing math" you probably were referring to "writing code to represent the math", not "telling the libraries to go away and do some math". So fair enough :-)
Steve Jessop
+2  A: 

Python 3.0:

>>> import math
>>> def remove_most_significant_digit(n, base=10):
...     return n % (base ** int(math.log(n, base)))
...
>>> def remove_least_significant_digit(n, base=10):
...     return int(n // base)
...
>>> remove_most_significant_digit(12345)
2345
>>> remove_least_significant_digit(12345)
1234
Stephan202
From this, I was able to come up with:def remove_most_significant_digits(n, base=10, digits=1): return n % (base ** int(math.log(n, base)-(digits-1)))Which suits my needs perfectly. Thanks!
Jeremy Frey
You're welcome :)
Stephan202
+1  A: 

You have to realize that numbers don't have digits, only strings do, and how many (and which) digits they have depends entirely on the base (which numbers don't have either). Internally, computers use what amounts to binary strings. So in general, manipulating base 10 digits requires you to convert the number to a string first - or do calculations that are the same you would do when converting it to a string. However, for your specific task of removing leading and trailing digits, these calculations (modulo and integer division) are very simple and much faster than converting the entire number.

Michael Borgwardt