tags:

views:

208

answers:

5

I'm looking for a function that will determine the value of a place given a number and a base. For example,

Given:

Whole Value: 1120
Base: 10
Place: Tens place

Should return: 2

Does anybody know the math for this?

Edit: The function is also expected to pass the whole value numerically, not as a string like "e328fa" or something. Also the return value should be numeric as well, so a FindInPlace(60 (whole value), 16 (base), 2 (place, 1-based index)) should return 3.

+3  A: 

If the number is already converted to an integer (i.e. base 10)

// Supports up to base 36
char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

char FindPlace(int number, int base, int digit)
{
   if(digit < 0) return 0;

   // Essentially divide the number by [base] to the [digit] power
   for(i=0; i<digit; i++)
   {
      number /= base;      
   }

   // TODO: Verify that the digit is in range of digits    
   return digits[number % base];
}

(0 gives you the right most digit, 1 gives you the next to right-most digit, etc)

I've returned the digit as a char, to allow for bases more than 10.

Note that if you want to allow the user to input the desired digit as "1s place, 10s place, 100s place" or "1s, 16s, 256s", you simply do

digit = log(PlaceValue, base);

or rewrite the code to be

char FindPlace(int number, int base, int digitAsBaseToAPower)
{
    // TODO: Error checking
    return digits[(number / digitAsBaseToAPower) % base];
}
Daniel LeCheminant
I should have specified that the number is passed numerically as opposed to a string notation. I edited the question to reflect this.
Ok, I'll edit my response to reflect this
Daniel LeCheminant
+1  A: 
int getPlace(float x, float place) {

    return (int)(x/place) % 10;
}

This works for base-10, and can handle places to the right or left of the decimal. You'd use it like this:

place = getPlace(1120,10);
otherPlace = getPlace(0.1120,1e-3);

A more general solution for any base is tricky. I'd go with a string solution.

Scottie T
+1 for handling the right of the decimal :]
Daniel LeCheminant
+1  A: 

Something like this?

int place_value(int value, int base, int place)
{
    int value_in_place= value;
    for (int place_index= 1; place_index<place; ++place_index)
    {
        value_in_place/=base;
    }

    return value_in_place % base;
}

where place is the one-based index of the digit you want from the right.

MSN
Are you sure it's a one-based index? I think place_value(10, 10, 1) will return 1, not 0...
Daniel LeCheminant
Yeah, I'm not getting the expected behavior using that.
Scottie T
Well, the fix is easy enough; simply say `for(int place_index=1;...)`
Daniel LeCheminant
place_value(1120,10,1) returns 2. I think you're off by a factor of base.
Scottie T
Err, I should have said zero-based index. Mea-culpa.
MSN
And thanks for the fix :)
MSN
This is a good answer too. I wish I could set more than one answer as the answer I was looking for.
A: 

The following method, placeValue, returns a char, because bases 11-36 have digits greater than 9. The method expects:

  • int value: the whole value
  • int base: the number base to convert the whole to; acceptable values are 2-36
  • int place: the index of the digit; the least significant digit has index 1


import java.math.BigInteger;

...

    private static char placeValue(int value, int base, int place) {
        BigInteger bigValue = BigInteger.valueOf(value);
        String baseString = bigValue.toString(base);
        int numDigits = baseString.length();
        int digitIndex = numDigits - place;
        char digit = baseString.charAt(digitIndex); 
        return digit;
    }
eleven81
+2  A: 

With 1-based place indexing the formula is:

placeval = floor(number / (base^(place-1))) mod base

In Python:

def FindInPlace(number, base, place):
    return number//base**(place-1) % base
Theran
Perfect. What does the double slash do?
The double slash is "floor division". It is the equivalent of int(floor(a/b)) without having to do any intermediate floating point math.
Theran