- 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;
}