Thread: Dissecting numbers

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    31

    Dissecting numbers

    In my program the user must enter a three-digit number. I need to set each of the three digits as a separate variable of type int, but I can only set the three-digit number as a single variable. Right now, my temporary solution is to tell the user to give each digit seperately, but I'd like to be able to take the three-digit number and dissect the numbers to create three one-digit numbers held in three different int variables.
    Can anyone help?

    -Thanks,
    Jeremy

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    int num = 123;

    Now print out what num/10 is, and what num%10 is
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2006
    Posts
    69
    Here is an idea for an algorithm. It might not be the best solution there is, but it'll probably work:

    The original, 3-digit number is called A
    Digit1 = A / 100
    Digit2 = (A - Digit1 * 100) / 10
    Digit3 = (A - Digit1 * 100 - Digit2 * 10)

    Edit: too late..

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    31
    Thanks alot C+/-, your algorithm works perfectly!

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by jmajeremy
    Thanks alot C+/-, your algorithm works perfectly!
    It is too complex
    Using Salem's advice you can bring it to:
    Code:
    Digit1 = A / 100
    Digit2 = (A %100) / 10
    Digit3 = A %10
    for example
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Code:
    int digit[3], tmp = num;
    for (int i=3; i--;) {
      digit[i] = tmp%10;
      tmp /= 10;
    }
    Then digit[0] = 1, digit[1] = 2, digit[2] = 3.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Eh, robatino, I think you should initialise i to 2, not 3.

    EDIT:
    No, I saw it wrongly: it does work, since you have a post-decrement. But that is, frankly, a hack that will confuse people, just as it confused me. I think it is easier to understand at a glance the more common idiom:
    Code:
    for (int i = 2; i >= 0; --i) {
        digit[i] = tmp % 10;
        tmp /= 10;
    }
    Last edited by laserlight; 12-31-2006 at 10:37 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Inside the loop i runs from 2 to 0. The i-- gets executed before the loop starts.

  9. #9
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    I think laserlight saw that, but it's not a very good place to put the post-decrement operator! It's just ... out of place compared to the norm. Especially for a beginner...

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    In this particular case efficiency isn't an issue, but if one works with large loops, it's the most concise and efficient way to loop from n-1 to 0. Also I like the fact that one can initialize to the actual number of elements n in the array, instead of n-1.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    In this particular case efficiency isn't an issue, but if one works with large loops, it's the most concise and efficient way to loop from n-1 to 0.
    Precisely: efficiency is not the issue here, but your version affects clarity, and so we can quote the maxim that premature optimisation is the root of all evil.

    Concerning efficiency: I am no expert in this area, but I doubt your version is measurably more efficient anyway. The normal idiom compares with zero, enters the loop body, and then decrements. Your version implicitly compares with zero, decrements, and then enters the loop body.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Clarity depends on what one is used to - the usual idiom for copying C-style strings
    Code:
      while (*s++ = *t++) ;
    is in my opinion much more cryptic, but it gets commonly used anyway (Kernighan and Ritchie actually recommend it!). As for efficiency, the comparison with zero is probably more efficient in my case, since as I understand it comparisons like <= require a subtraction, as opposed to != which is just a bitwise comparison. Your version can't use !=, since it needs to allow 0 as a possible value (although it could if the loop went up instead of down), and also has to use a signed integral type as the loop variable, which halves the maximum range of the loop (although again this isn't necessary if the loop goes up).

    Edit: Sorry, actually your version _could_ use != but only as "i != -1".
    Last edited by robatino; 12-31-2006 at 11:37 AM.

  13. #13
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
    for (int i=3; i--;)
    Problem with the above pattern that on the first glance it is read as
    for (int i=3; i>0 ; i--) due to standard usage of the for loop
    only on the third glance the code is read as it is written... And this makes it hard to understand and possible source of bugs when someone comes to modify it...

    If I had to write something like that I'll go on the laserlight's solution or:
    Code:
    for (int i=3; i>0;) 
    {
       i--;
       etc
    }
    But of course if the code is not supposed to be maintained - it is not an issue...
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Clarity depends on what one is used to
    I agree. In this case, your version is not what people would be used to, and considering that jmajeremy needed help for such a relatively trivial problem, it is reasonable to expect that jmajeremy lacks experience in C++, and possibly computer programming in general. As such, it makes sense to give examples that are along common lines, especially since the usual idiom is more general (loop from some high index to some low index).

    As for efficiency, the comparison with zero is probably more efficient in my case, since as I understand it comparisons like <= require a subtraction, as opposed to != which is just a bitwise comparison.
    It is possible to do a bitwise comparison to test for such inequalities, of course. Anyway, the compiler may well be able to optimise the code such that it performs no worse than your version.

    and also has to use a signed integral type as the loop variable, which halves the maximum range of the loop (although again this isn't necessary if the loop goes up).
    True, but that does not matter at all here. Even for a 400-bit integer an 8-bit signed char as the loop index would be good enough (though also a little strange, heh).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Quote Originally Posted by laserlight
    I agree. In this case, your version is not what people would be used to,
    But they should be familiar with it, or at least have seen it a few times. Looping between 0 and n-1 is a basic operation, and the most concise/efficient ways of doing it are
    Code:
    for (int i=0; i != n; i++) {}
    upwards, and
    Code:
    for (int i=n; i--;) {}
    downwards. These also allow using an unsigned index, and have the clarity of referring to n instead of n-1. This is a very small amount of information to store in one's bag of tricks, and doesn't require thought once one knows it. (I think the "premature optimization" quote refers to something that requires effort.) But most people, even experienced ones, won't consider doing it unless they've seen it in someone else's code. This is one of those cases where the best tool for the job has fallen through the cracks because of the self-fulfilling prophecy of everyone being afraid of confusing everyone else. The danger of temporary confusion is small compared to the possible benefit of learning an idiom which can be used routinely. This applies to maintaining other people's code as well as learning to code. I could have avoided using the idiom on the grounds that it's not needed on efficiency or range grounds here, but then jmajeremy probably never would have seen it again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with Rational Numbers (C++)
    By cloudjc in forum C++ Programming
    Replies: 3
    Last Post: 04-28-2008, 04:03 PM
  2. Comparing numbers to a list of numbers held in a text file
    By jmajeremy in forum C++ Programming
    Replies: 3
    Last Post: 11-06-2006, 07:56 AM
  3. Logical errors with seach function
    By Taka in forum C Programming
    Replies: 4
    Last Post: 09-18-2006, 05:20 AM
  4. the definition of a mathematical "average" or "mean"
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 12-03-2002, 11:15 AM
  5. A (complex) question on numbers
    By Unregistered in forum C++ Programming
    Replies: 8
    Last Post: 02-03-2002, 06:38 PM