Reputation: 16724
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
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
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
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
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