Tech Support > Computers & Technology > Programming > programming problem
programming problem
Posted by John Smith on June 1st, 2005


Apologies for the vague subject line.

The problem is to find the nth most significant
digit of a multi-digit decimal number using only
numerical methods. That is, no fair converting
the number to a string. My first crack at it
would go something like this:

input: n=6342 d=3

iterate the following loop d times
this is the 1st pass

p = (int)log10(n) = 3
q = 10 ^ p = 1000
r = n(mod q) = 342
s = n - r = 6000
t = s / q = 6
n = r = 342

after 3 passes the output (t) is 4

Seems like a lot of steps. Is there a more
efficient way?

-JS

Posted by Willem on June 1st, 2005


John wrote:
) Apologies for the vague subject line.
)
) The problem is to find the nth most significant
) digit of a multi-digit decimal number using only
) numerical methods. That is, no fair converting
) the number to a string. My first crack at it
) would go something like this:
)
) input: n=6342 d=3
)
) iterate the following loop d times
) this is the 1st pass
)
) p = (int)log10(n) = 3
) q = 10 ^ p = 1000
) r = n(mod q) = 342
) s = n - r = 6000
) t = s / q = 6
) n = r = 342
)
) after 3 passes the output (t) is 4
)
) Seems like a lot of steps. Is there a more
) efficient way?

Of course there is, blatantly simple even.
Just divide by the appropriate power of 10 then do a modulo-10.
Who posed you this odd problem ?


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

Posted by Tony on June 1st, 2005


"Willem" <willem@stack.nl> wrote in message
news:slrnd9s946.22gc.willem@toad.stack.nl...
The class syllabus, perhaps?



Posted by John Smith on June 2nd, 2005


Willem wrote:

It's a class problem, but not mine. I'm self-taught (can't you tell?).
The specification requires that the input to the program be the number
itself and a 2nd number specifying the digit to be returned, as in the
example I gave. So, for example, if I want the 3rd most significant
digit in 6342, the input is 6342 and 3.

Here's what I came up with, based on your suggestion. Thanks.

/* get_digit() returns the nth msd of number
using only numerical methods */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double get_digit(double number, int digit);

int main(int argc, char* argv[])
{
int number, d;

if(argc < 3)exit(EXIT_FAILURE);
number = strtod(argv[1], NULL);
d = atoi(argv[2]);
printf("%.f\n", get_digit(number, d));

return 0;
}

double get_digit(double number, int digit)
{
double pow10, r, s, ndigits;

ndigits = (int)log10(number) + 1;
pow10 = pow(10, ndigits-digit);
r = number / pow10;
s = floor(r);

return remainder(s, 10.0);
}



Posted by Martijn on June 2nd, 2005


[snipped]

Still far too complex. Just a hint: you don't need much more than the
divide and modulo suggested earlier. Another hint: the modulo operator is
written as %.
E.g.:

i = 37 % 10;

The result of that statement is that i contains 7.

The implementation would be no more than 3 lines (4 including a blank one).

--
Martijn
http://www.sereneconcepts.nl



Posted by jg.campbell.ng@gmail.com on June 3rd, 2005


John Smith wrote:

Agreed with previous poster -- far too complex. But if you are
self-teaching, it is hard for you to know. In a course, the instructor
might have issued guidelines for solution of such a problem.

Dunno why, but whenever I find myself using 'pow' or 'log', I figure
I've done something kludgy.

After a while, you will gain an instinct on what looks right.

Are you following any textbook? There are some very good textbooks
available now; the standard of programming teaching resources has
advanced rather stupendously in the last ten years. Hence, no excuse
for using a bad textbook or some rubbish off the web.

Incidentally, where does 'remainder' come from?

After achieving a solution with divide and %, maybe you could think a
little about specification (requirements). For example (he says,
avoiding any attempt at a complete spec.!):

- are the numbers integers or are floats (. + fractional part) allowed?
Maybe inclusion of floats makes no difference;

- are the digits labelled from most significant or least significant?
Does labelling start at 0 or 1?

- what should happen if you execute the program as:

prog x n

where n is outside the possible range of labels in x?

- what if a user types x as 000012345.678? input conversion will
discard the leading 0s, but is this what is required?

And specification leads to testing.

Best regards,

Jon C.


Posted by John Smith on June 3rd, 2005


jg.campbell.ng@gmail.com wrote:

Do you mean to say that you never need to do exponentiation, or that
there is a less kludgy way in C than the library function pow()? I am
mostly interested in numerical programming and I don't see how I could
do without these math functions for very long.
I have, of course, read K&R. Also, "C Primer Plus" by Stephen Prata, and
as a reference, "C A Reference Manual" by Harbison & Steele. C texts are
getting harder and harder to find in bookstores. It's mostly C++ and C#
nowadays.

The standard C library. Prototyped in math.h.
Now explicit spec on this. I am assuming input to be integers.
Labelled from most significant, starting with 1.
Output the nth most significant digit of x.
For purposes of the exercise, it's assumed input is appropriate.
I got rid of the fp types, writing my own function for exponentiation
with integer input/output. This gets it down to 3 lines -- sort of.

/* get_digit() returns the nth msd of a number
using only numerical methods */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int get_digit(int number, int digit);
int int_pow(int base, int x);

int main(int argc, char* argv[])
{
int number, d;

if(argc < 3)exit(EXIT_FAILURE);
number = atoi(argv[1]);
d = atoi(argv[2]);
printf("%d\n", get_digit(number, d));

return 0;
}

int get_digit(int number, int digit)
{
int pow10, r, ndigits;

ndigits = (int)log10(number) + 1;
pow10 = int_pow(10, ndigits-digit);
r = number / pow10;

return r % 10;
}

/* exponentiation with integer input/output */
int int_pow(int base, int x)
{
int result = 1;
while (x != 0)
{
if ((x % 2) == 1)
result *= base;
base = base * base;
x = x / 2;
}
return result;
}




Similar Posts