Jack
Jack

Reputation: 16724

How to get the first x (leftmost) digits of a decimal number

Let's assume that I have n=1234 and I want to get the first x digits of n. Assume x=2, in C math I just compute 1234/100 and I will get 12. But how can I do it programatically? I.e., using math. I have implemented it by the horrible way, converting to string and putting a 0 at x position. If possible, I want to avoid built-in C functions because my goal is to convert the algorithm to assembly language later.

Upvotes: 2

Views: 7912

Answers (4)

bluesummers
bluesummers

Reputation: 12607

int getLeftDigits(double num, double numOfDigits)
{
double divider = pow(10, numOfDigits);

if (num < divider)
    return num;

getLeftDigits(num/10, numOfDigits);
}

If you want to avoid the use of the pow function, you can just implement it by yourself as shown in one of the other comments here.

Upvotes: 1

MOHAMED
MOHAMED

Reputation: 43518

You can use the following algorithm: keep divide the n per 10 till you get n < 10^x

here after the code

int power10(int x) {
    int p = 1;
    while (x) {
        p *= 10;
        x--;
    }
    return p;
}

int main (void) {

    int x = 2;
    int n = 1234;
    int max = power10(x);

    int res = n;   
    while(res>=max)
        res = res/10;

   printf("%d\n",res);
}

Upvotes: 1

Mark Ransom
Mark Ransom

Reputation: 308130

Without using any library functions, the best way to do it is with brute force. The maximum value an integer can take is 2147483648 so we won't deal with anything over that.

int first_two(int value)
{
    assert(value >= 0);  // unspecified for negative numbers
    if (value >= 1000000000)
        return value / 100000000;
    if (value >= 100000000)
        return value / 10000000;
    if (value >= 10000000)
        return value / 1000000;
    if (value >= 1000000)
        return value / 100000;
    if (value >= 100000)
        return value / 10000;
    if (value >= 10000)
        return value / 1000;
    if (value >= 1000)
        return value / 100;
    if (value >= 100)
        return value / 10;
    return value;
}

Upvotes: 4

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726509

You can do it programmatically by taking the floor of the decimal logarithm of your number (in case of 1234, it's floor(3.091315), which is 3), adding one, and subtracting n - the desired number of decimal digits. This would give you x such that integer-dividing the original value by 10^x gives you the desired result:

#include <math.h>
...
int num = 12345;
int n = 3;
int log10 = (log(num)/log(10))+1;
int divisor = pow(10, log10-n);
int res = num / divisor;
printf("%d\n", res);

Here is a demo on ideone.

Converting the above to assembly would be tricky because of the math functions involved. You can simplify it by defining a table of powers of ten, searching it for the first item that's greater than or equal to the desired number (giving you log10 above) and then grabbing the log10-n-th entry, giving you pow(10, log10-n):

int pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};

int main(void) {
    int num = 12345;
    int n = 3;
    int log10 = 0;
    while (pow10[log10] < num) {
        log10++;
    }
    int divisor = pow10[log10-n];
    int res = num / divisor;
    printf("log10(num)+1=%d, divisor=%d, result=%d\n", log10, divisor, res);
    return 0;
}

Here is the modified demo.

Upvotes: 1

Related Questions