My professor says my digit summing code is flawed. Is he right?Modulo operation with negative numbersModulo operator with negative valuesHow is if statement evaluated in c++?Does either ANSI C or ISO C specify what -5 % 10 should be?Is negating INT_MIN undefined behaviour?Can I rely on % (modulo) operator in C for negative numbers?Variable leading zeroes in C99 printfSimple Rand() functionsscanf %u not intepreting hexadecimalC - Returning negative value as unsigned sets errno?Normalize random value of _int64strtoul of negative numberHow to get every digit from a number in C?

Type and strength of a typical chain

How do I weigh a kitchen island to determine what size castors to get?

Does these arithmetic means on Pythagorean triangles converge?

My name was added to manuscript as co-author without my consent; how to get it removed?

SSH from a shared workplace computer

Prove the inequality is true

What are the different ways one can refer to the home in everyday French

How to remind myself to lock my doors

Can you use wish to cast a level 9 spell?

How could "aggressor" pilots fly foreign aircraft without speaking the language?

What is the word for things that work even when they aren't working - e.g escalators?

Song in C major has F# note

How to execute a project with two resources where you need three resources?

I'm largest when I'm five, what am I?

Self organizing bonuses?

How does the Trump administration justify tariffs on luxury goods?

How to use an equalizer?

Disrespectful employee going above my head and telling me what to do. I am his manager

Based on true story rules

Test if two foods are the same

Sanitise a high score table to remove offensive terms / usernames

Does Windows 10 Fast Startup feature drain battery while laptop is turned off?

What kind of screwdriver can unscrew this?

Can the bass be used instead of drums?



My professor says my digit summing code is flawed. Is he right?


Modulo operation with negative numbersModulo operator with negative valuesHow is if statement evaluated in c++?Does either ANSI C or ISO C specify what -5 % 10 should be?Is negating INT_MIN undefined behaviour?Can I rely on % (modulo) operator in C for negative numbers?Variable leading zeroes in C99 printfSimple Rand() functionsscanf %u not intepreting hexadecimalC - Returning negative value as unsigned sets errno?Normalize random value of _int64strtoul of negative numberHow to get every digit from a number in C?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









10

















I recently had a test in my class. One of the problems was the following:




Given a number n, write a function in C/C++ that returns the sum of the digits of the number squared. (The following is important). The range of n is [ -(10^7), 10^7 ]. Example: If n = 123, your function should return 14 (1^2 + 2^2 + 3^2 = 14).




This is the function that I wrote:



int sum_of_digits_squared(int n) 


int s = 0, c;

while (n)
c = n % 10;
s += (c * c);
n /= 10;


return s;



Looked right to me. So now the test came back and I found that the teacher didn't give me all the points for a reason that I do not understand. According to him, for my function to be complete, I should've have added the following detail:



int sum_of_digits_squared(int n) 


int s = 0, c;

if (n == 0) //
return 0; //
//
// THIS APPARENTLY SHOULD'VE
if (n < 0) // BEEN IN THE FUNCTION FOR IT
n = n * (-1); // TO BE CORRECT
//

while (n)
c = n % 10;
s += (c * c);
n /= 10;


return s;



The argument for this is that the number n is in the range [-(10^7), 10^7], so it can be a negative number. But I don't see where my own version of the function fails. If I understand correctly, the meaning of while(n) is while(n != 0), not while (n > 0), so in my version of the function the number n wouldn't fail to enter the loop. It would work just the same.



Then, I tried both versions of the function on my computer at home and I got exactly the same answers for all the examples that I tried. So, sum_of_digits_squared(-123) is equal to sum_of_digits_squared(123) (which again, is equal to 14) (even without the detail that I apparently should've added). Indeed, if I try to print on the screen the digits of the number (from least to greatest in importance), in the 123 case I get 3 2 1 and in the -123 case I get -3 -2 -1 (which is actually kind of interesting). But in this problem it wouldn't matter since we square the digits.



So, who's wrong?



EDIT: My bad, I forgot to specify and didn't know it was important. The version of C used in our class and tests has to be C99 or newer. So I guess (by reading the comments) that my version would get the correct answer in any way.










share|improve this question




























  • Comments are not for extended discussion; this conversation has been moved to chat.

    – Brad Larson
    3 hours ago

















10

















I recently had a test in my class. One of the problems was the following:




Given a number n, write a function in C/C++ that returns the sum of the digits of the number squared. (The following is important). The range of n is [ -(10^7), 10^7 ]. Example: If n = 123, your function should return 14 (1^2 + 2^2 + 3^2 = 14).




This is the function that I wrote:



int sum_of_digits_squared(int n) 


int s = 0, c;

while (n)
c = n % 10;
s += (c * c);
n /= 10;


return s;



Looked right to me. So now the test came back and I found that the teacher didn't give me all the points for a reason that I do not understand. According to him, for my function to be complete, I should've have added the following detail:



int sum_of_digits_squared(int n) 


int s = 0, c;

if (n == 0) //
return 0; //
//
// THIS APPARENTLY SHOULD'VE
if (n < 0) // BEEN IN THE FUNCTION FOR IT
n = n * (-1); // TO BE CORRECT
//

while (n)
c = n % 10;
s += (c * c);
n /= 10;


return s;



The argument for this is that the number n is in the range [-(10^7), 10^7], so it can be a negative number. But I don't see where my own version of the function fails. If I understand correctly, the meaning of while(n) is while(n != 0), not while (n > 0), so in my version of the function the number n wouldn't fail to enter the loop. It would work just the same.



Then, I tried both versions of the function on my computer at home and I got exactly the same answers for all the examples that I tried. So, sum_of_digits_squared(-123) is equal to sum_of_digits_squared(123) (which again, is equal to 14) (even without the detail that I apparently should've added). Indeed, if I try to print on the screen the digits of the number (from least to greatest in importance), in the 123 case I get 3 2 1 and in the -123 case I get -3 -2 -1 (which is actually kind of interesting). But in this problem it wouldn't matter since we square the digits.



So, who's wrong?



EDIT: My bad, I forgot to specify and didn't know it was important. The version of C used in our class and tests has to be C99 or newer. So I guess (by reading the comments) that my version would get the correct answer in any way.










share|improve this question




























  • Comments are not for extended discussion; this conversation has been moved to chat.

    – Brad Larson
    3 hours ago













10












10








10








I recently had a test in my class. One of the problems was the following:




Given a number n, write a function in C/C++ that returns the sum of the digits of the number squared. (The following is important). The range of n is [ -(10^7), 10^7 ]. Example: If n = 123, your function should return 14 (1^2 + 2^2 + 3^2 = 14).




This is the function that I wrote:



int sum_of_digits_squared(int n) 


int s = 0, c;

while (n)
c = n % 10;
s += (c * c);
n /= 10;


return s;



Looked right to me. So now the test came back and I found that the teacher didn't give me all the points for a reason that I do not understand. According to him, for my function to be complete, I should've have added the following detail:



int sum_of_digits_squared(int n) 


int s = 0, c;

if (n == 0) //
return 0; //
//
// THIS APPARENTLY SHOULD'VE
if (n < 0) // BEEN IN THE FUNCTION FOR IT
n = n * (-1); // TO BE CORRECT
//

while (n)
c = n % 10;
s += (c * c);
n /= 10;


return s;



The argument for this is that the number n is in the range [-(10^7), 10^7], so it can be a negative number. But I don't see where my own version of the function fails. If I understand correctly, the meaning of while(n) is while(n != 0), not while (n > 0), so in my version of the function the number n wouldn't fail to enter the loop. It would work just the same.



Then, I tried both versions of the function on my computer at home and I got exactly the same answers for all the examples that I tried. So, sum_of_digits_squared(-123) is equal to sum_of_digits_squared(123) (which again, is equal to 14) (even without the detail that I apparently should've added). Indeed, if I try to print on the screen the digits of the number (from least to greatest in importance), in the 123 case I get 3 2 1 and in the -123 case I get -3 -2 -1 (which is actually kind of interesting). But in this problem it wouldn't matter since we square the digits.



So, who's wrong?



EDIT: My bad, I forgot to specify and didn't know it was important. The version of C used in our class and tests has to be C99 or newer. So I guess (by reading the comments) that my version would get the correct answer in any way.










share|improve this question
















I recently had a test in my class. One of the problems was the following:




Given a number n, write a function in C/C++ that returns the sum of the digits of the number squared. (The following is important). The range of n is [ -(10^7), 10^7 ]. Example: If n = 123, your function should return 14 (1^2 + 2^2 + 3^2 = 14).




This is the function that I wrote:



int sum_of_digits_squared(int n) 


int s = 0, c;

while (n)
c = n % 10;
s += (c * c);
n /= 10;


return s;



Looked right to me. So now the test came back and I found that the teacher didn't give me all the points for a reason that I do not understand. According to him, for my function to be complete, I should've have added the following detail:



int sum_of_digits_squared(int n) 


int s = 0, c;

if (n == 0) //
return 0; //
//
// THIS APPARENTLY SHOULD'VE
if (n < 0) // BEEN IN THE FUNCTION FOR IT
n = n * (-1); // TO BE CORRECT
//

while (n)
c = n % 10;
s += (c * c);
n /= 10;


return s;



The argument for this is that the number n is in the range [-(10^7), 10^7], so it can be a negative number. But I don't see where my own version of the function fails. If I understand correctly, the meaning of while(n) is while(n != 0), not while (n > 0), so in my version of the function the number n wouldn't fail to enter the loop. It would work just the same.



Then, I tried both versions of the function on my computer at home and I got exactly the same answers for all the examples that I tried. So, sum_of_digits_squared(-123) is equal to sum_of_digits_squared(123) (which again, is equal to 14) (even without the detail that I apparently should've added). Indeed, if I try to print on the screen the digits of the number (from least to greatest in importance), in the 123 case I get 3 2 1 and in the -123 case I get -3 -2 -1 (which is actually kind of interesting). But in this problem it wouldn't matter since we square the digits.



So, who's wrong?



EDIT: My bad, I forgot to specify and didn't know it was important. The version of C used in our class and tests has to be C99 or newer. So I guess (by reading the comments) that my version would get the correct answer in any way.







c






share|improve this question















share|improve this question













share|improve this question




share|improve this question



share|improve this question








edited 4 hours ago









klutt

11.8k11 gold badges28 silver badges50 bronze badges




11.8k11 gold badges28 silver badges50 bronze badges










asked 8 hours ago









Bogdan VladBogdan Vlad

806 bronze badges




806 bronze badges















  • Comments are not for extended discussion; this conversation has been moved to chat.

    – Brad Larson
    3 hours ago

















  • Comments are not for extended discussion; this conversation has been moved to chat.

    – Brad Larson
    3 hours ago
















Comments are not for extended discussion; this conversation has been moved to chat.

– Brad Larson
3 hours ago





Comments are not for extended discussion; this conversation has been moved to chat.

– Brad Larson
3 hours ago












7 Answers
7






active

oldest

votes


















9


















Summarizing a discussion that's been percolating in the comments:



  • There is no good reason to test in advance for n == 0. The while(n) test will handle that case perfectly.

  • It's likely your teacher is still used to earlier times, when the result of % with negative operands was differently defined. On some old systems (including, notably, early Unix on a PDP-11, where Dennis Ritchie originally developed C), the result of a % b was always in the range [0 .. b-1], meaning that -123 % 10 was 7. On such a system, the test in advance for n < 0 would be necessary.

But the second bullet applies only to earlier times. In the current versions of both the C and C++ standards, integer division is defined to truncate towards 0, so it turns out that n % 10 is guaranteed to give you the (possibly negative) last digit of n even when n is negative.



So the answer to the question "What is the meaning of while(n)?" is "Exactly the same as while(n != 0)", and the answer to "Will this code work properly for negative as well as positive n?" is "Yes, under any modern, Standards-confirming compiler." The answer to the question "Then why did the instructor mark it down?" is probably that they're not aware of a significant language redefinition that happened to C in 1999 and to C++ in 2010 or so.






share|improve this answer




























  • I edited my question. Forgot to mention the version. It's C99 or a newer version of C.

    – Bogdan Vlad
    7 hours ago


















4


















Your code is perfectly fine



You are absolutely correct and your teacher is wrong. There is absolutely no reason at all to add that extra complexity, since it does not affect the result at all. It even introduces a bug. (See below)



First, the check if n is zero is obviously completely unnecessary and this is very easy to realize. To be honest, I actually question your teachers competence if he have objections about this. But I guess everybody can have brain farts from time to time.



The second one is a bit more understandable, but he is still wrong.



This is what the C11 standard 6.5.5.p6 says:




If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a; otherwise, the behavior of both a/b and a%b is undefined.




Actually, even C89 says the same and I cannot imagine that you're using an older C-version than that.



And in your case c/n is defined for all c and n. It would only be undefined if n=0 but since n!=0 is the condition for entering the loop, it's fine. According to the standard, this implies that c%n is defined for all c and n.



So there's absolutely nothing wrong with doing modulo with negative numbers. And since you're squaring the result, there is no problem at all.



Your teachers code is flawed



Yes, it actually is. If the input is INT_MIN and the architecture is using two's complement AND if the bit pattern where the sign bit is 1 and all value bits are 0 is NOT a trap value (using two's complement without trap values is very common) then your teachers code will yield undefined behavior. Your code is - if even so slightly - better than his. And considering introducing a small bug by making the code unnecessary complex and gaining absolutely zero value, I'd say that your code is MUCH better.



But then again, your teacher explicitly says that n should be in the range [-(10^7), 10^7]. So that could have saved him, if it were not for the case that int is not necessarily a 32 bit integer. If you compile it for a 16-bit architecture, both of your code snippets are flawed. To avoid this, you can use int32_t instead. Then you will be safe.



EDIT:



As pointed out by Andrew Henle in comments, int32_t is not required by the standard, so to be 100% portable, use int_least32_t or int_fast32_t instead.






share|improve this answer




























  • If the input is INT_MIN and the architecture is using two's complement (which is very common) then your teachers code will yield undefined behavior. Ouch. That will leave a mark. ;-)

    – Andrew Henle
    4 hours ago












  • @AndrewHenle Yeah, I got really happy when that train of thought came through my brain. I'm so hoping OP will show that to his teacher. XD

    – klutt
    4 hours ago











  • That's some really nice bug spotting, too. I'm just hoping the teacher isn't one of THOSE that punish students for proving them wrong.

    – Andrew Henle
    4 hours ago






  • 1





    @AndrewHenle I agree. That's a theoretical matter. But look one more time. I spotted that the teachers (and OP:s) used a data type that is not guaranteed to be able to represent all the values in the input set. :D

    – klutt
    3 hours ago






  • 1





    Another good catch. I think you could make a good living selling your services doing code reviews. ;-) But pedantically, int32_t is an optional type - int_least32_t and int_fast32_t are required types.

    – Andrew Henle
    2 hours ago


















0


















A while loop in almost every programming languge checks if the value given by the express is "truthy". In C and C++ "truthy" is defined as non-zero. For the most part although it can different some circumstances while(n) is the same thing as saying while(n != 0) which uses an expression n != 0 that evaluates to either 1 or 0 based on the truth of the expression.






share|improve this answer









New contributor



conner wallace is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





















  • What about the negative modulus issue? Are you siding with the OP or the professor?

    – John Kugelman
    8 hours ago






  • 1





    "although it can different some circumstances while(n) is the same thing as saying while(n != 0)" -- Under what circumstances would they not be equivalent?

    – Carey Gregory
    7 hours ago











  • @CareyGregory In C++ while(n) could end up calling a user-defined conversion function such as a member function explicit operator bool() ...

    – Kevin
    7 hours ago











  • @Kevin Oh, with C++ sure, but I was thinking C since this question is tagged C.

    – Carey Gregory
    2 hours ago











  • @CareyGregory It was previously also tagged C++

    – Kevin
    2 hours ago


















0


















I don't completely like either your version or your teacher's. Your teacher's version does the extra tests that you correctly point out are unnecessary. C's mod operator is not a proper mathematical mod: a negative number mod 10 will produce a negative result (proper mathematical modulus is always non-negative). But since you're squaring it anyway, no difference.



But this is far from obvious, so I would add to your code not the checks of your teacher, but a big comment that explains why it works. E.g.:



/* NOTE: This works for negative values, because the modulus gets squared */






share|improve this answer

































    0


















    NOTE: AS I was writing this answer, you did clarify that you are using C. The majority of my answer is about C++. However, since your title still has C++ and the question is still tagged C++, I have chosen to answer anyway in case this is still useful to other people, especially since most of the answers I've seen till now are mostly unsatisfactory.



    In modern C++ (Note: I don't really know where C stands on this), your professor seems to be wrong on both counts.



    First is this part right here:



    if (n == 0) 
    return 0;



    In C++, this is basically the same thing as:



    if (!n) 
    return 0;



    That means your while is equivalent to something like this:



    while(n != 0) 
    // some implementation



    That means since you are merely exiting in your if when the while wouldn't execute anyway, there really isn't a reason to put this if here, since what you are doing after the loop and in the if are equivalent anyway. Although I should say that is for some reason these were different, you'd need to have this if.



    So really, this if statement isn't particularly useful unless I'm mistaken.



    The second part is where things get hairy:



    if (n < 0) 
    n = n * (-1);



    The heart of the issue is is what the output of the modulus of a negative number outputs.



    In modern C++, this seems to be mostly well defined:





    The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined. For integral operands the / operator yields the algebraic quotient with any fractional part discarded; if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a.





    And later:





    If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.





    As the poster of the quoted answer correctly points out, the important part of this equation right here:




    (a/b)*b + a%b




    Taking an example of your case, you'd get something like this:



    -13/ 10 = -1 (integer truncation)
    -1 * 10 = -10
    -13 - (-10) = -13 + 10 = -3


    The only catch is that last line:




    If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.




    That means that in a case like this, only the sign seems to be implementation-defined. That shouldn't be a problem in your case because, because you are squaring this value anyway.



    That said, keep in mind that this doesn't necessarily apply to earlier versions of C++, or C99. If that is what your professor is using, that could be why.




    EDIT: Nope, I'm wrong. This seems to be the case for C99 or later as well:




    C99 requires that when a/b is representable:



    (a/b) * b + a%b shall equal a




    And another place:





    When integers are divided and the division is inexact, if both operands are positive the result of the / operator is the largest integer less than the algebraic quotient and the result of the % operator is positive. If either operand is negative, whether the result of the / operator is the largest integer less than the algebraic quotient or the smallest integer greater than the algebraic quotient is implementation-defined, as is the sign of the result of the % operator. If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.




    Does either ANSI C or ISO C specify what -5 % 10 should be?




    So, yeah. Even in C99, this doesn't seem to affect you. The equation is the same.






    share|improve this answer



































      -1


















      What Conner Wallace wrote was correct.



      Basically inside,
      while ( x ) -- means:
      run loop as long as



      • x is not 0 or 0.0

      • not null

      • not end of string terminator ()

      that is "x" can be integer, float, char , char *, void * etc... but you can use single form!!



      For experienced users, it is easily understandable, convenient instead of comparing to explicit data of each type accordingly.



      Also consider simplicity:



      int sum(int n) 
      int sum=0;

      for(int i=1;i<=n;i++)
      sum += i;

      return sum;



      `



      To :
      //Basically same loop backwards, but less elements



      int sum(int n) 
      int sum=n;

      while ( n-- )
      sum += n;

      return sum;






      share|improve this answer

































        -4


















        while(n) basically means to execute the body of the loop until the value of n>0 because any value other than 0 means true.



        Let's say, initially n=123



        Step 1- while(123)=>while(true) so enters into the body
        c= 123%10 =3 s=0+(3*3)=9 n=123/10=12
        Step 2- while(12) =>while(true)
        c= 12%10 =2 s = 9+4 = 13 n=12/10=1
        Step 3- while(1)=> while(true)
        c= 1%10 = 1 s=13+1 =14 n=1/10=0
        Step 4- while(0)=> while(False) so loop will terminate





        share|improve this answer





















        • 2





          What are you getting at? It sounds like you're just restating the OP's case that while (n) is fine. Except, as they point out, it's equivalent to while (n != 0) not while (n > 0).

          – John Kugelman
          8 hours ago













        Your Answer






        StackExchange.ifUsing("editor", function ()
        StackExchange.using("externalEditor", function ()
        StackExchange.using("snippets", function ()
        StackExchange.snippets.init();
        );
        );
        , "code-snippets");

        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "1"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader:
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        ,
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );














        draft saved

        draft discarded
















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f58224638%2fmy-professor-says-my-digit-summing-code-is-flawed-is-he-right%23new-answer', 'question_page');

        );

        Post as a guest















        Required, but never shown


























        7 Answers
        7






        active

        oldest

        votes








        7 Answers
        7






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        9


















        Summarizing a discussion that's been percolating in the comments:



        • There is no good reason to test in advance for n == 0. The while(n) test will handle that case perfectly.

        • It's likely your teacher is still used to earlier times, when the result of % with negative operands was differently defined. On some old systems (including, notably, early Unix on a PDP-11, where Dennis Ritchie originally developed C), the result of a % b was always in the range [0 .. b-1], meaning that -123 % 10 was 7. On such a system, the test in advance for n < 0 would be necessary.

        But the second bullet applies only to earlier times. In the current versions of both the C and C++ standards, integer division is defined to truncate towards 0, so it turns out that n % 10 is guaranteed to give you the (possibly negative) last digit of n even when n is negative.



        So the answer to the question "What is the meaning of while(n)?" is "Exactly the same as while(n != 0)", and the answer to "Will this code work properly for negative as well as positive n?" is "Yes, under any modern, Standards-confirming compiler." The answer to the question "Then why did the instructor mark it down?" is probably that they're not aware of a significant language redefinition that happened to C in 1999 and to C++ in 2010 or so.






        share|improve this answer




























        • I edited my question. Forgot to mention the version. It's C99 or a newer version of C.

          – Bogdan Vlad
          7 hours ago















        9


















        Summarizing a discussion that's been percolating in the comments:



        • There is no good reason to test in advance for n == 0. The while(n) test will handle that case perfectly.

        • It's likely your teacher is still used to earlier times, when the result of % with negative operands was differently defined. On some old systems (including, notably, early Unix on a PDP-11, where Dennis Ritchie originally developed C), the result of a % b was always in the range [0 .. b-1], meaning that -123 % 10 was 7. On such a system, the test in advance for n < 0 would be necessary.

        But the second bullet applies only to earlier times. In the current versions of both the C and C++ standards, integer division is defined to truncate towards 0, so it turns out that n % 10 is guaranteed to give you the (possibly negative) last digit of n even when n is negative.



        So the answer to the question "What is the meaning of while(n)?" is "Exactly the same as while(n != 0)", and the answer to "Will this code work properly for negative as well as positive n?" is "Yes, under any modern, Standards-confirming compiler." The answer to the question "Then why did the instructor mark it down?" is probably that they're not aware of a significant language redefinition that happened to C in 1999 and to C++ in 2010 or so.






        share|improve this answer




























        • I edited my question. Forgot to mention the version. It's C99 or a newer version of C.

          – Bogdan Vlad
          7 hours ago













        9














        9










        9









        Summarizing a discussion that's been percolating in the comments:



        • There is no good reason to test in advance for n == 0. The while(n) test will handle that case perfectly.

        • It's likely your teacher is still used to earlier times, when the result of % with negative operands was differently defined. On some old systems (including, notably, early Unix on a PDP-11, where Dennis Ritchie originally developed C), the result of a % b was always in the range [0 .. b-1], meaning that -123 % 10 was 7. On such a system, the test in advance for n < 0 would be necessary.

        But the second bullet applies only to earlier times. In the current versions of both the C and C++ standards, integer division is defined to truncate towards 0, so it turns out that n % 10 is guaranteed to give you the (possibly negative) last digit of n even when n is negative.



        So the answer to the question "What is the meaning of while(n)?" is "Exactly the same as while(n != 0)", and the answer to "Will this code work properly for negative as well as positive n?" is "Yes, under any modern, Standards-confirming compiler." The answer to the question "Then why did the instructor mark it down?" is probably that they're not aware of a significant language redefinition that happened to C in 1999 and to C++ in 2010 or so.






        share|improve this answer
















        Summarizing a discussion that's been percolating in the comments:



        • There is no good reason to test in advance for n == 0. The while(n) test will handle that case perfectly.

        • It's likely your teacher is still used to earlier times, when the result of % with negative operands was differently defined. On some old systems (including, notably, early Unix on a PDP-11, where Dennis Ritchie originally developed C), the result of a % b was always in the range [0 .. b-1], meaning that -123 % 10 was 7. On such a system, the test in advance for n < 0 would be necessary.

        But the second bullet applies only to earlier times. In the current versions of both the C and C++ standards, integer division is defined to truncate towards 0, so it turns out that n % 10 is guaranteed to give you the (possibly negative) last digit of n even when n is negative.



        So the answer to the question "What is the meaning of while(n)?" is "Exactly the same as while(n != 0)", and the answer to "Will this code work properly for negative as well as positive n?" is "Yes, under any modern, Standards-confirming compiler." The answer to the question "Then why did the instructor mark it down?" is probably that they're not aware of a significant language redefinition that happened to C in 1999 and to C++ in 2010 or so.







        share|improve this answer















        share|improve this answer




        share|improve this answer



        share|improve this answer








        edited 3 hours ago

























        answered 7 hours ago









        Steve SummitSteve Summit

        22.3k2 gold badges29 silver badges52 bronze badges




        22.3k2 gold badges29 silver badges52 bronze badges















        • I edited my question. Forgot to mention the version. It's C99 or a newer version of C.

          – Bogdan Vlad
          7 hours ago

















        • I edited my question. Forgot to mention the version. It's C99 or a newer version of C.

          – Bogdan Vlad
          7 hours ago
















        I edited my question. Forgot to mention the version. It's C99 or a newer version of C.

        – Bogdan Vlad
        7 hours ago





        I edited my question. Forgot to mention the version. It's C99 or a newer version of C.

        – Bogdan Vlad
        7 hours ago













        4


















        Your code is perfectly fine



        You are absolutely correct and your teacher is wrong. There is absolutely no reason at all to add that extra complexity, since it does not affect the result at all. It even introduces a bug. (See below)



        First, the check if n is zero is obviously completely unnecessary and this is very easy to realize. To be honest, I actually question your teachers competence if he have objections about this. But I guess everybody can have brain farts from time to time.



        The second one is a bit more understandable, but he is still wrong.



        This is what the C11 standard 6.5.5.p6 says:




        If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a; otherwise, the behavior of both a/b and a%b is undefined.




        Actually, even C89 says the same and I cannot imagine that you're using an older C-version than that.



        And in your case c/n is defined for all c and n. It would only be undefined if n=0 but since n!=0 is the condition for entering the loop, it's fine. According to the standard, this implies that c%n is defined for all c and n.



        So there's absolutely nothing wrong with doing modulo with negative numbers. And since you're squaring the result, there is no problem at all.



        Your teachers code is flawed



        Yes, it actually is. If the input is INT_MIN and the architecture is using two's complement AND if the bit pattern where the sign bit is 1 and all value bits are 0 is NOT a trap value (using two's complement without trap values is very common) then your teachers code will yield undefined behavior. Your code is - if even so slightly - better than his. And considering introducing a small bug by making the code unnecessary complex and gaining absolutely zero value, I'd say that your code is MUCH better.



        But then again, your teacher explicitly says that n should be in the range [-(10^7), 10^7]. So that could have saved him, if it were not for the case that int is not necessarily a 32 bit integer. If you compile it for a 16-bit architecture, both of your code snippets are flawed. To avoid this, you can use int32_t instead. Then you will be safe.



        EDIT:



        As pointed out by Andrew Henle in comments, int32_t is not required by the standard, so to be 100% portable, use int_least32_t or int_fast32_t instead.






        share|improve this answer




























        • If the input is INT_MIN and the architecture is using two's complement (which is very common) then your teachers code will yield undefined behavior. Ouch. That will leave a mark. ;-)

          – Andrew Henle
          4 hours ago












        • @AndrewHenle Yeah, I got really happy when that train of thought came through my brain. I'm so hoping OP will show that to his teacher. XD

          – klutt
          4 hours ago











        • That's some really nice bug spotting, too. I'm just hoping the teacher isn't one of THOSE that punish students for proving them wrong.

          – Andrew Henle
          4 hours ago






        • 1





          @AndrewHenle I agree. That's a theoretical matter. But look one more time. I spotted that the teachers (and OP:s) used a data type that is not guaranteed to be able to represent all the values in the input set. :D

          – klutt
          3 hours ago






        • 1





          Another good catch. I think you could make a good living selling your services doing code reviews. ;-) But pedantically, int32_t is an optional type - int_least32_t and int_fast32_t are required types.

          – Andrew Henle
          2 hours ago















        4


















        Your code is perfectly fine



        You are absolutely correct and your teacher is wrong. There is absolutely no reason at all to add that extra complexity, since it does not affect the result at all. It even introduces a bug. (See below)



        First, the check if n is zero is obviously completely unnecessary and this is very easy to realize. To be honest, I actually question your teachers competence if he have objections about this. But I guess everybody can have brain farts from time to time.



        The second one is a bit more understandable, but he is still wrong.



        This is what the C11 standard 6.5.5.p6 says:




        If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a; otherwise, the behavior of both a/b and a%b is undefined.




        Actually, even C89 says the same and I cannot imagine that you're using an older C-version than that.



        And in your case c/n is defined for all c and n. It would only be undefined if n=0 but since n!=0 is the condition for entering the loop, it's fine. According to the standard, this implies that c%n is defined for all c and n.



        So there's absolutely nothing wrong with doing modulo with negative numbers. And since you're squaring the result, there is no problem at all.



        Your teachers code is flawed



        Yes, it actually is. If the input is INT_MIN and the architecture is using two's complement AND if the bit pattern where the sign bit is 1 and all value bits are 0 is NOT a trap value (using two's complement without trap values is very common) then your teachers code will yield undefined behavior. Your code is - if even so slightly - better than his. And considering introducing a small bug by making the code unnecessary complex and gaining absolutely zero value, I'd say that your code is MUCH better.



        But then again, your teacher explicitly says that n should be in the range [-(10^7), 10^7]. So that could have saved him, if it were not for the case that int is not necessarily a 32 bit integer. If you compile it for a 16-bit architecture, both of your code snippets are flawed. To avoid this, you can use int32_t instead. Then you will be safe.



        EDIT:



        As pointed out by Andrew Henle in comments, int32_t is not required by the standard, so to be 100% portable, use int_least32_t or int_fast32_t instead.






        share|improve this answer




























        • If the input is INT_MIN and the architecture is using two's complement (which is very common) then your teachers code will yield undefined behavior. Ouch. That will leave a mark. ;-)

          – Andrew Henle
          4 hours ago












        • @AndrewHenle Yeah, I got really happy when that train of thought came through my brain. I'm so hoping OP will show that to his teacher. XD

          – klutt
          4 hours ago











        • That's some really nice bug spotting, too. I'm just hoping the teacher isn't one of THOSE that punish students for proving them wrong.

          – Andrew Henle
          4 hours ago






        • 1





          @AndrewHenle I agree. That's a theoretical matter. But look one more time. I spotted that the teachers (and OP:s) used a data type that is not guaranteed to be able to represent all the values in the input set. :D

          – klutt
          3 hours ago






        • 1





          Another good catch. I think you could make a good living selling your services doing code reviews. ;-) But pedantically, int32_t is an optional type - int_least32_t and int_fast32_t are required types.

          – Andrew Henle
          2 hours ago













        4














        4










        4









        Your code is perfectly fine



        You are absolutely correct and your teacher is wrong. There is absolutely no reason at all to add that extra complexity, since it does not affect the result at all. It even introduces a bug. (See below)



        First, the check if n is zero is obviously completely unnecessary and this is very easy to realize. To be honest, I actually question your teachers competence if he have objections about this. But I guess everybody can have brain farts from time to time.



        The second one is a bit more understandable, but he is still wrong.



        This is what the C11 standard 6.5.5.p6 says:




        If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a; otherwise, the behavior of both a/b and a%b is undefined.




        Actually, even C89 says the same and I cannot imagine that you're using an older C-version than that.



        And in your case c/n is defined for all c and n. It would only be undefined if n=0 but since n!=0 is the condition for entering the loop, it's fine. According to the standard, this implies that c%n is defined for all c and n.



        So there's absolutely nothing wrong with doing modulo with negative numbers. And since you're squaring the result, there is no problem at all.



        Your teachers code is flawed



        Yes, it actually is. If the input is INT_MIN and the architecture is using two's complement AND if the bit pattern where the sign bit is 1 and all value bits are 0 is NOT a trap value (using two's complement without trap values is very common) then your teachers code will yield undefined behavior. Your code is - if even so slightly - better than his. And considering introducing a small bug by making the code unnecessary complex and gaining absolutely zero value, I'd say that your code is MUCH better.



        But then again, your teacher explicitly says that n should be in the range [-(10^7), 10^7]. So that could have saved him, if it were not for the case that int is not necessarily a 32 bit integer. If you compile it for a 16-bit architecture, both of your code snippets are flawed. To avoid this, you can use int32_t instead. Then you will be safe.



        EDIT:



        As pointed out by Andrew Henle in comments, int32_t is not required by the standard, so to be 100% portable, use int_least32_t or int_fast32_t instead.






        share|improve this answer
















        Your code is perfectly fine



        You are absolutely correct and your teacher is wrong. There is absolutely no reason at all to add that extra complexity, since it does not affect the result at all. It even introduces a bug. (See below)



        First, the check if n is zero is obviously completely unnecessary and this is very easy to realize. To be honest, I actually question your teachers competence if he have objections about this. But I guess everybody can have brain farts from time to time.



        The second one is a bit more understandable, but he is still wrong.



        This is what the C11 standard 6.5.5.p6 says:




        If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a; otherwise, the behavior of both a/b and a%b is undefined.




        Actually, even C89 says the same and I cannot imagine that you're using an older C-version than that.



        And in your case c/n is defined for all c and n. It would only be undefined if n=0 but since n!=0 is the condition for entering the loop, it's fine. According to the standard, this implies that c%n is defined for all c and n.



        So there's absolutely nothing wrong with doing modulo with negative numbers. And since you're squaring the result, there is no problem at all.



        Your teachers code is flawed



        Yes, it actually is. If the input is INT_MIN and the architecture is using two's complement AND if the bit pattern where the sign bit is 1 and all value bits are 0 is NOT a trap value (using two's complement without trap values is very common) then your teachers code will yield undefined behavior. Your code is - if even so slightly - better than his. And considering introducing a small bug by making the code unnecessary complex and gaining absolutely zero value, I'd say that your code is MUCH better.



        But then again, your teacher explicitly says that n should be in the range [-(10^7), 10^7]. So that could have saved him, if it were not for the case that int is not necessarily a 32 bit integer. If you compile it for a 16-bit architecture, both of your code snippets are flawed. To avoid this, you can use int32_t instead. Then you will be safe.



        EDIT:



        As pointed out by Andrew Henle in comments, int32_t is not required by the standard, so to be 100% portable, use int_least32_t or int_fast32_t instead.







        share|improve this answer















        share|improve this answer




        share|improve this answer



        share|improve this answer








        edited 2 hours ago

























        answered 7 hours ago









        kluttklutt

        11.8k11 gold badges28 silver badges50 bronze badges




        11.8k11 gold badges28 silver badges50 bronze badges















        • If the input is INT_MIN and the architecture is using two's complement (which is very common) then your teachers code will yield undefined behavior. Ouch. That will leave a mark. ;-)

          – Andrew Henle
          4 hours ago












        • @AndrewHenle Yeah, I got really happy when that train of thought came through my brain. I'm so hoping OP will show that to his teacher. XD

          – klutt
          4 hours ago











        • That's some really nice bug spotting, too. I'm just hoping the teacher isn't one of THOSE that punish students for proving them wrong.

          – Andrew Henle
          4 hours ago






        • 1





          @AndrewHenle I agree. That's a theoretical matter. But look one more time. I spotted that the teachers (and OP:s) used a data type that is not guaranteed to be able to represent all the values in the input set. :D

          – klutt
          3 hours ago






        • 1





          Another good catch. I think you could make a good living selling your services doing code reviews. ;-) But pedantically, int32_t is an optional type - int_least32_t and int_fast32_t are required types.

          – Andrew Henle
          2 hours ago

















        • If the input is INT_MIN and the architecture is using two's complement (which is very common) then your teachers code will yield undefined behavior. Ouch. That will leave a mark. ;-)

          – Andrew Henle
          4 hours ago












        • @AndrewHenle Yeah, I got really happy when that train of thought came through my brain. I'm so hoping OP will show that to his teacher. XD

          – klutt
          4 hours ago











        • That's some really nice bug spotting, too. I'm just hoping the teacher isn't one of THOSE that punish students for proving them wrong.

          – Andrew Henle
          4 hours ago






        • 1





          @AndrewHenle I agree. That's a theoretical matter. But look one more time. I spotted that the teachers (and OP:s) used a data type that is not guaranteed to be able to represent all the values in the input set. :D

          – klutt
          3 hours ago






        • 1





          Another good catch. I think you could make a good living selling your services doing code reviews. ;-) But pedantically, int32_t is an optional type - int_least32_t and int_fast32_t are required types.

          – Andrew Henle
          2 hours ago
















        If the input is INT_MIN and the architecture is using two's complement (which is very common) then your teachers code will yield undefined behavior. Ouch. That will leave a mark. ;-)

        – Andrew Henle
        4 hours ago






        If the input is INT_MIN and the architecture is using two's complement (which is very common) then your teachers code will yield undefined behavior. Ouch. That will leave a mark. ;-)

        – Andrew Henle
        4 hours ago














        @AndrewHenle Yeah, I got really happy when that train of thought came through my brain. I'm so hoping OP will show that to his teacher. XD

        – klutt
        4 hours ago





        @AndrewHenle Yeah, I got really happy when that train of thought came through my brain. I'm so hoping OP will show that to his teacher. XD

        – klutt
        4 hours ago













        That's some really nice bug spotting, too. I'm just hoping the teacher isn't one of THOSE that punish students for proving them wrong.

        – Andrew Henle
        4 hours ago





        That's some really nice bug spotting, too. I'm just hoping the teacher isn't one of THOSE that punish students for proving them wrong.

        – Andrew Henle
        4 hours ago




        1




        1





        @AndrewHenle I agree. That's a theoretical matter. But look one more time. I spotted that the teachers (and OP:s) used a data type that is not guaranteed to be able to represent all the values in the input set. :D

        – klutt
        3 hours ago





        @AndrewHenle I agree. That's a theoretical matter. But look one more time. I spotted that the teachers (and OP:s) used a data type that is not guaranteed to be able to represent all the values in the input set. :D

        – klutt
        3 hours ago




        1




        1





        Another good catch. I think you could make a good living selling your services doing code reviews. ;-) But pedantically, int32_t is an optional type - int_least32_t and int_fast32_t are required types.

        – Andrew Henle
        2 hours ago





        Another good catch. I think you could make a good living selling your services doing code reviews. ;-) But pedantically, int32_t is an optional type - int_least32_t and int_fast32_t are required types.

        – Andrew Henle
        2 hours ago











        0


















        A while loop in almost every programming languge checks if the value given by the express is "truthy". In C and C++ "truthy" is defined as non-zero. For the most part although it can different some circumstances while(n) is the same thing as saying while(n != 0) which uses an expression n != 0 that evaluates to either 1 or 0 based on the truth of the expression.






        share|improve this answer









        New contributor



        conner wallace is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.





















        • What about the negative modulus issue? Are you siding with the OP or the professor?

          – John Kugelman
          8 hours ago






        • 1





          "although it can different some circumstances while(n) is the same thing as saying while(n != 0)" -- Under what circumstances would they not be equivalent?

          – Carey Gregory
          7 hours ago











        • @CareyGregory In C++ while(n) could end up calling a user-defined conversion function such as a member function explicit operator bool() ...

          – Kevin
          7 hours ago











        • @Kevin Oh, with C++ sure, but I was thinking C since this question is tagged C.

          – Carey Gregory
          2 hours ago











        • @CareyGregory It was previously also tagged C++

          – Kevin
          2 hours ago















        0


















        A while loop in almost every programming languge checks if the value given by the express is "truthy". In C and C++ "truthy" is defined as non-zero. For the most part although it can different some circumstances while(n) is the same thing as saying while(n != 0) which uses an expression n != 0 that evaluates to either 1 or 0 based on the truth of the expression.






        share|improve this answer









        New contributor



        conner wallace is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.





















        • What about the negative modulus issue? Are you siding with the OP or the professor?

          – John Kugelman
          8 hours ago






        • 1





          "although it can different some circumstances while(n) is the same thing as saying while(n != 0)" -- Under what circumstances would they not be equivalent?

          – Carey Gregory
          7 hours ago











        • @CareyGregory In C++ while(n) could end up calling a user-defined conversion function such as a member function explicit operator bool() ...

          – Kevin
          7 hours ago











        • @Kevin Oh, with C++ sure, but I was thinking C since this question is tagged C.

          – Carey Gregory
          2 hours ago











        • @CareyGregory It was previously also tagged C++

          – Kevin
          2 hours ago













        0














        0










        0









        A while loop in almost every programming languge checks if the value given by the express is "truthy". In C and C++ "truthy" is defined as non-zero. For the most part although it can different some circumstances while(n) is the same thing as saying while(n != 0) which uses an expression n != 0 that evaluates to either 1 or 0 based on the truth of the expression.






        share|improve this answer









        New contributor



        conner wallace is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        A while loop in almost every programming languge checks if the value given by the express is "truthy". In C and C++ "truthy" is defined as non-zero. For the most part although it can different some circumstances while(n) is the same thing as saying while(n != 0) which uses an expression n != 0 that evaluates to either 1 or 0 based on the truth of the expression.







        share|improve this answer









        New contributor



        conner wallace is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.








        share|improve this answer




        share|improve this answer



        share|improve this answer






        New contributor



        conner wallace is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.








        answered 8 hours ago









        conner wallaceconner wallace

        211 bronze badge




        211 bronze badge




        New contributor



        conner wallace is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.




        New contributor




        conner wallace is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.

















        • What about the negative modulus issue? Are you siding with the OP or the professor?

          – John Kugelman
          8 hours ago






        • 1





          "although it can different some circumstances while(n) is the same thing as saying while(n != 0)" -- Under what circumstances would they not be equivalent?

          – Carey Gregory
          7 hours ago











        • @CareyGregory In C++ while(n) could end up calling a user-defined conversion function such as a member function explicit operator bool() ...

          – Kevin
          7 hours ago











        • @Kevin Oh, with C++ sure, but I was thinking C since this question is tagged C.

          – Carey Gregory
          2 hours ago











        • @CareyGregory It was previously also tagged C++

          – Kevin
          2 hours ago

















        • What about the negative modulus issue? Are you siding with the OP or the professor?

          – John Kugelman
          8 hours ago






        • 1





          "although it can different some circumstances while(n) is the same thing as saying while(n != 0)" -- Under what circumstances would they not be equivalent?

          – Carey Gregory
          7 hours ago











        • @CareyGregory In C++ while(n) could end up calling a user-defined conversion function such as a member function explicit operator bool() ...

          – Kevin
          7 hours ago











        • @Kevin Oh, with C++ sure, but I was thinking C since this question is tagged C.

          – Carey Gregory
          2 hours ago











        • @CareyGregory It was previously also tagged C++

          – Kevin
          2 hours ago
















        What about the negative modulus issue? Are you siding with the OP or the professor?

        – John Kugelman
        8 hours ago





        What about the negative modulus issue? Are you siding with the OP or the professor?

        – John Kugelman
        8 hours ago




        1




        1





        "although it can different some circumstances while(n) is the same thing as saying while(n != 0)" -- Under what circumstances would they not be equivalent?

        – Carey Gregory
        7 hours ago





        "although it can different some circumstances while(n) is the same thing as saying while(n != 0)" -- Under what circumstances would they not be equivalent?

        – Carey Gregory
        7 hours ago













        @CareyGregory In C++ while(n) could end up calling a user-defined conversion function such as a member function explicit operator bool() ...

        – Kevin
        7 hours ago





        @CareyGregory In C++ while(n) could end up calling a user-defined conversion function such as a member function explicit operator bool() ...

        – Kevin
        7 hours ago













        @Kevin Oh, with C++ sure, but I was thinking C since this question is tagged C.

        – Carey Gregory
        2 hours ago





        @Kevin Oh, with C++ sure, but I was thinking C since this question is tagged C.

        – Carey Gregory
        2 hours ago













        @CareyGregory It was previously also tagged C++

        – Kevin
        2 hours ago





        @CareyGregory It was previously also tagged C++

        – Kevin
        2 hours ago











        0


















        I don't completely like either your version or your teacher's. Your teacher's version does the extra tests that you correctly point out are unnecessary. C's mod operator is not a proper mathematical mod: a negative number mod 10 will produce a negative result (proper mathematical modulus is always non-negative). But since you're squaring it anyway, no difference.



        But this is far from obvious, so I would add to your code not the checks of your teacher, but a big comment that explains why it works. E.g.:



        /* NOTE: This works for negative values, because the modulus gets squared */






        share|improve this answer






























          0


















          I don't completely like either your version or your teacher's. Your teacher's version does the extra tests that you correctly point out are unnecessary. C's mod operator is not a proper mathematical mod: a negative number mod 10 will produce a negative result (proper mathematical modulus is always non-negative). But since you're squaring it anyway, no difference.



          But this is far from obvious, so I would add to your code not the checks of your teacher, but a big comment that explains why it works. E.g.:



          /* NOTE: This works for negative values, because the modulus gets squared */






          share|improve this answer




























            0














            0










            0









            I don't completely like either your version or your teacher's. Your teacher's version does the extra tests that you correctly point out are unnecessary. C's mod operator is not a proper mathematical mod: a negative number mod 10 will produce a negative result (proper mathematical modulus is always non-negative). But since you're squaring it anyway, no difference.



            But this is far from obvious, so I would add to your code not the checks of your teacher, but a big comment that explains why it works. E.g.:



            /* NOTE: This works for negative values, because the modulus gets squared */






            share|improve this answer














            I don't completely like either your version or your teacher's. Your teacher's version does the extra tests that you correctly point out are unnecessary. C's mod operator is not a proper mathematical mod: a negative number mod 10 will produce a negative result (proper mathematical modulus is always non-negative). But since you're squaring it anyway, no difference.



            But this is far from obvious, so I would add to your code not the checks of your teacher, but a big comment that explains why it works. E.g.:



            /* NOTE: This works for negative values, because the modulus gets squared */







            share|improve this answer













            share|improve this answer




            share|improve this answer



            share|improve this answer










            answered 7 hours ago









            Lee Daniel CrockerLee Daniel Crocker

            10.8k1 gold badge21 silver badges42 bronze badges




            10.8k1 gold badge21 silver badges42 bronze badges
























                0


















                NOTE: AS I was writing this answer, you did clarify that you are using C. The majority of my answer is about C++. However, since your title still has C++ and the question is still tagged C++, I have chosen to answer anyway in case this is still useful to other people, especially since most of the answers I've seen till now are mostly unsatisfactory.



                In modern C++ (Note: I don't really know where C stands on this), your professor seems to be wrong on both counts.



                First is this part right here:



                if (n == 0) 
                return 0;



                In C++, this is basically the same thing as:



                if (!n) 
                return 0;



                That means your while is equivalent to something like this:



                while(n != 0) 
                // some implementation



                That means since you are merely exiting in your if when the while wouldn't execute anyway, there really isn't a reason to put this if here, since what you are doing after the loop and in the if are equivalent anyway. Although I should say that is for some reason these were different, you'd need to have this if.



                So really, this if statement isn't particularly useful unless I'm mistaken.



                The second part is where things get hairy:



                if (n < 0) 
                n = n * (-1);



                The heart of the issue is is what the output of the modulus of a negative number outputs.



                In modern C++, this seems to be mostly well defined:





                The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined. For integral operands the / operator yields the algebraic quotient with any fractional part discarded; if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a.





                And later:





                If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.





                As the poster of the quoted answer correctly points out, the important part of this equation right here:




                (a/b)*b + a%b




                Taking an example of your case, you'd get something like this:



                -13/ 10 = -1 (integer truncation)
                -1 * 10 = -10
                -13 - (-10) = -13 + 10 = -3


                The only catch is that last line:




                If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.




                That means that in a case like this, only the sign seems to be implementation-defined. That shouldn't be a problem in your case because, because you are squaring this value anyway.



                That said, keep in mind that this doesn't necessarily apply to earlier versions of C++, or C99. If that is what your professor is using, that could be why.




                EDIT: Nope, I'm wrong. This seems to be the case for C99 or later as well:




                C99 requires that when a/b is representable:



                (a/b) * b + a%b shall equal a




                And another place:





                When integers are divided and the division is inexact, if both operands are positive the result of the / operator is the largest integer less than the algebraic quotient and the result of the % operator is positive. If either operand is negative, whether the result of the / operator is the largest integer less than the algebraic quotient or the smallest integer greater than the algebraic quotient is implementation-defined, as is the sign of the result of the % operator. If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.




                Does either ANSI C or ISO C specify what -5 % 10 should be?




                So, yeah. Even in C99, this doesn't seem to affect you. The equation is the same.






                share|improve this answer
































                  0


















                  NOTE: AS I was writing this answer, you did clarify that you are using C. The majority of my answer is about C++. However, since your title still has C++ and the question is still tagged C++, I have chosen to answer anyway in case this is still useful to other people, especially since most of the answers I've seen till now are mostly unsatisfactory.



                  In modern C++ (Note: I don't really know where C stands on this), your professor seems to be wrong on both counts.



                  First is this part right here:



                  if (n == 0) 
                  return 0;



                  In C++, this is basically the same thing as:



                  if (!n) 
                  return 0;



                  That means your while is equivalent to something like this:



                  while(n != 0) 
                  // some implementation



                  That means since you are merely exiting in your if when the while wouldn't execute anyway, there really isn't a reason to put this if here, since what you are doing after the loop and in the if are equivalent anyway. Although I should say that is for some reason these were different, you'd need to have this if.



                  So really, this if statement isn't particularly useful unless I'm mistaken.



                  The second part is where things get hairy:



                  if (n < 0) 
                  n = n * (-1);



                  The heart of the issue is is what the output of the modulus of a negative number outputs.



                  In modern C++, this seems to be mostly well defined:





                  The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined. For integral operands the / operator yields the algebraic quotient with any fractional part discarded; if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a.





                  And later:





                  If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.





                  As the poster of the quoted answer correctly points out, the important part of this equation right here:




                  (a/b)*b + a%b




                  Taking an example of your case, you'd get something like this:



                  -13/ 10 = -1 (integer truncation)
                  -1 * 10 = -10
                  -13 - (-10) = -13 + 10 = -3


                  The only catch is that last line:




                  If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.




                  That means that in a case like this, only the sign seems to be implementation-defined. That shouldn't be a problem in your case because, because you are squaring this value anyway.



                  That said, keep in mind that this doesn't necessarily apply to earlier versions of C++, or C99. If that is what your professor is using, that could be why.




                  EDIT: Nope, I'm wrong. This seems to be the case for C99 or later as well:




                  C99 requires that when a/b is representable:



                  (a/b) * b + a%b shall equal a




                  And another place:





                  When integers are divided and the division is inexact, if both operands are positive the result of the / operator is the largest integer less than the algebraic quotient and the result of the % operator is positive. If either operand is negative, whether the result of the / operator is the largest integer less than the algebraic quotient or the smallest integer greater than the algebraic quotient is implementation-defined, as is the sign of the result of the % operator. If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.




                  Does either ANSI C or ISO C specify what -5 % 10 should be?




                  So, yeah. Even in C99, this doesn't seem to affect you. The equation is the same.






                  share|improve this answer






























                    0














                    0










                    0









                    NOTE: AS I was writing this answer, you did clarify that you are using C. The majority of my answer is about C++. However, since your title still has C++ and the question is still tagged C++, I have chosen to answer anyway in case this is still useful to other people, especially since most of the answers I've seen till now are mostly unsatisfactory.



                    In modern C++ (Note: I don't really know where C stands on this), your professor seems to be wrong on both counts.



                    First is this part right here:



                    if (n == 0) 
                    return 0;



                    In C++, this is basically the same thing as:



                    if (!n) 
                    return 0;



                    That means your while is equivalent to something like this:



                    while(n != 0) 
                    // some implementation



                    That means since you are merely exiting in your if when the while wouldn't execute anyway, there really isn't a reason to put this if here, since what you are doing after the loop and in the if are equivalent anyway. Although I should say that is for some reason these were different, you'd need to have this if.



                    So really, this if statement isn't particularly useful unless I'm mistaken.



                    The second part is where things get hairy:



                    if (n < 0) 
                    n = n * (-1);



                    The heart of the issue is is what the output of the modulus of a negative number outputs.



                    In modern C++, this seems to be mostly well defined:





                    The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined. For integral operands the / operator yields the algebraic quotient with any fractional part discarded; if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a.





                    And later:





                    If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.





                    As the poster of the quoted answer correctly points out, the important part of this equation right here:




                    (a/b)*b + a%b




                    Taking an example of your case, you'd get something like this:



                    -13/ 10 = -1 (integer truncation)
                    -1 * 10 = -10
                    -13 - (-10) = -13 + 10 = -3


                    The only catch is that last line:




                    If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.




                    That means that in a case like this, only the sign seems to be implementation-defined. That shouldn't be a problem in your case because, because you are squaring this value anyway.



                    That said, keep in mind that this doesn't necessarily apply to earlier versions of C++, or C99. If that is what your professor is using, that could be why.




                    EDIT: Nope, I'm wrong. This seems to be the case for C99 or later as well:




                    C99 requires that when a/b is representable:



                    (a/b) * b + a%b shall equal a




                    And another place:





                    When integers are divided and the division is inexact, if both operands are positive the result of the / operator is the largest integer less than the algebraic quotient and the result of the % operator is positive. If either operand is negative, whether the result of the / operator is the largest integer less than the algebraic quotient or the smallest integer greater than the algebraic quotient is implementation-defined, as is the sign of the result of the % operator. If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.




                    Does either ANSI C or ISO C specify what -5 % 10 should be?




                    So, yeah. Even in C99, this doesn't seem to affect you. The equation is the same.






                    share|improve this answer
















                    NOTE: AS I was writing this answer, you did clarify that you are using C. The majority of my answer is about C++. However, since your title still has C++ and the question is still tagged C++, I have chosen to answer anyway in case this is still useful to other people, especially since most of the answers I've seen till now are mostly unsatisfactory.



                    In modern C++ (Note: I don't really know where C stands on this), your professor seems to be wrong on both counts.



                    First is this part right here:



                    if (n == 0) 
                    return 0;



                    In C++, this is basically the same thing as:



                    if (!n) 
                    return 0;



                    That means your while is equivalent to something like this:



                    while(n != 0) 
                    // some implementation



                    That means since you are merely exiting in your if when the while wouldn't execute anyway, there really isn't a reason to put this if here, since what you are doing after the loop and in the if are equivalent anyway. Although I should say that is for some reason these were different, you'd need to have this if.



                    So really, this if statement isn't particularly useful unless I'm mistaken.



                    The second part is where things get hairy:



                    if (n < 0) 
                    n = n * (-1);



                    The heart of the issue is is what the output of the modulus of a negative number outputs.



                    In modern C++, this seems to be mostly well defined:





                    The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined. For integral operands the / operator yields the algebraic quotient with any fractional part discarded; if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a.





                    And later:





                    If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.





                    As the poster of the quoted answer correctly points out, the important part of this equation right here:




                    (a/b)*b + a%b




                    Taking an example of your case, you'd get something like this:



                    -13/ 10 = -1 (integer truncation)
                    -1 * 10 = -10
                    -13 - (-10) = -13 + 10 = -3


                    The only catch is that last line:




                    If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.




                    That means that in a case like this, only the sign seems to be implementation-defined. That shouldn't be a problem in your case because, because you are squaring this value anyway.



                    That said, keep in mind that this doesn't necessarily apply to earlier versions of C++, or C99. If that is what your professor is using, that could be why.




                    EDIT: Nope, I'm wrong. This seems to be the case for C99 or later as well:




                    C99 requires that when a/b is representable:



                    (a/b) * b + a%b shall equal a




                    And another place:





                    When integers are divided and the division is inexact, if both operands are positive the result of the / operator is the largest integer less than the algebraic quotient and the result of the % operator is positive. If either operand is negative, whether the result of the / operator is the largest integer less than the algebraic quotient or the smallest integer greater than the algebraic quotient is implementation-defined, as is the sign of the result of the % operator. If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.




                    Does either ANSI C or ISO C specify what -5 % 10 should be?




                    So, yeah. Even in C99, this doesn't seem to affect you. The equation is the same.







                    share|improve this answer















                    share|improve this answer




                    share|improve this answer



                    share|improve this answer








                    edited 6 hours ago

























                    answered 7 hours ago









                    ChipsterChipster

                    2,5062 gold badges7 silver badges25 bronze badges




                    2,5062 gold badges7 silver badges25 bronze badges
























                        -1


















                        What Conner Wallace wrote was correct.



                        Basically inside,
                        while ( x ) -- means:
                        run loop as long as



                        • x is not 0 or 0.0

                        • not null

                        • not end of string terminator ()

                        that is "x" can be integer, float, char , char *, void * etc... but you can use single form!!



                        For experienced users, it is easily understandable, convenient instead of comparing to explicit data of each type accordingly.



                        Also consider simplicity:



                        int sum(int n) 
                        int sum=0;

                        for(int i=1;i<=n;i++)
                        sum += i;

                        return sum;



                        `



                        To :
                        //Basically same loop backwards, but less elements



                        int sum(int n) 
                        int sum=n;

                        while ( n-- )
                        sum += n;

                        return sum;






                        share|improve this answer






























                          -1


















                          What Conner Wallace wrote was correct.



                          Basically inside,
                          while ( x ) -- means:
                          run loop as long as



                          • x is not 0 or 0.0

                          • not null

                          • not end of string terminator ()

                          that is "x" can be integer, float, char , char *, void * etc... but you can use single form!!



                          For experienced users, it is easily understandable, convenient instead of comparing to explicit data of each type accordingly.



                          Also consider simplicity:



                          int sum(int n) 
                          int sum=0;

                          for(int i=1;i<=n;i++)
                          sum += i;

                          return sum;



                          `



                          To :
                          //Basically same loop backwards, but less elements



                          int sum(int n) 
                          int sum=n;

                          while ( n-- )
                          sum += n;

                          return sum;






                          share|improve this answer




























                            -1














                            -1










                            -1









                            What Conner Wallace wrote was correct.



                            Basically inside,
                            while ( x ) -- means:
                            run loop as long as



                            • x is not 0 or 0.0

                            • not null

                            • not end of string terminator ()

                            that is "x" can be integer, float, char , char *, void * etc... but you can use single form!!



                            For experienced users, it is easily understandable, convenient instead of comparing to explicit data of each type accordingly.



                            Also consider simplicity:



                            int sum(int n) 
                            int sum=0;

                            for(int i=1;i<=n;i++)
                            sum += i;

                            return sum;



                            `



                            To :
                            //Basically same loop backwards, but less elements



                            int sum(int n) 
                            int sum=n;

                            while ( n-- )
                            sum += n;

                            return sum;






                            share|improve this answer














                            What Conner Wallace wrote was correct.



                            Basically inside,
                            while ( x ) -- means:
                            run loop as long as



                            • x is not 0 or 0.0

                            • not null

                            • not end of string terminator ()

                            that is "x" can be integer, float, char , char *, void * etc... but you can use single form!!



                            For experienced users, it is easily understandable, convenient instead of comparing to explicit data of each type accordingly.



                            Also consider simplicity:



                            int sum(int n) 
                            int sum=0;

                            for(int i=1;i<=n;i++)
                            sum += i;

                            return sum;



                            `



                            To :
                            //Basically same loop backwards, but less elements



                            int sum(int n) 
                            int sum=n;

                            while ( n-- )
                            sum += n;

                            return sum;







                            share|improve this answer













                            share|improve this answer




                            share|improve this answer



                            share|improve this answer










                            answered 7 hours ago









                            Jay Kumar RJay Kumar R

                            4132 silver badges7 bronze badges




                            4132 silver badges7 bronze badges
























                                -4


















                                while(n) basically means to execute the body of the loop until the value of n>0 because any value other than 0 means true.



                                Let's say, initially n=123



                                Step 1- while(123)=>while(true) so enters into the body
                                c= 123%10 =3 s=0+(3*3)=9 n=123/10=12
                                Step 2- while(12) =>while(true)
                                c= 12%10 =2 s = 9+4 = 13 n=12/10=1
                                Step 3- while(1)=> while(true)
                                c= 1%10 = 1 s=13+1 =14 n=1/10=0
                                Step 4- while(0)=> while(False) so loop will terminate





                                share|improve this answer





















                                • 2





                                  What are you getting at? It sounds like you're just restating the OP's case that while (n) is fine. Except, as they point out, it's equivalent to while (n != 0) not while (n > 0).

                                  – John Kugelman
                                  8 hours ago
















                                -4


















                                while(n) basically means to execute the body of the loop until the value of n>0 because any value other than 0 means true.



                                Let's say, initially n=123



                                Step 1- while(123)=>while(true) so enters into the body
                                c= 123%10 =3 s=0+(3*3)=9 n=123/10=12
                                Step 2- while(12) =>while(true)
                                c= 12%10 =2 s = 9+4 = 13 n=12/10=1
                                Step 3- while(1)=> while(true)
                                c= 1%10 = 1 s=13+1 =14 n=1/10=0
                                Step 4- while(0)=> while(False) so loop will terminate





                                share|improve this answer





















                                • 2





                                  What are you getting at? It sounds like you're just restating the OP's case that while (n) is fine. Except, as they point out, it's equivalent to while (n != 0) not while (n > 0).

                                  – John Kugelman
                                  8 hours ago














                                -4














                                -4










                                -4









                                while(n) basically means to execute the body of the loop until the value of n>0 because any value other than 0 means true.



                                Let's say, initially n=123



                                Step 1- while(123)=>while(true) so enters into the body
                                c= 123%10 =3 s=0+(3*3)=9 n=123/10=12
                                Step 2- while(12) =>while(true)
                                c= 12%10 =2 s = 9+4 = 13 n=12/10=1
                                Step 3- while(1)=> while(true)
                                c= 1%10 = 1 s=13+1 =14 n=1/10=0
                                Step 4- while(0)=> while(False) so loop will terminate





                                share|improve this answer














                                while(n) basically means to execute the body of the loop until the value of n>0 because any value other than 0 means true.



                                Let's say, initially n=123



                                Step 1- while(123)=>while(true) so enters into the body
                                c= 123%10 =3 s=0+(3*3)=9 n=123/10=12
                                Step 2- while(12) =>while(true)
                                c= 12%10 =2 s = 9+4 = 13 n=12/10=1
                                Step 3- while(1)=> while(true)
                                c= 1%10 = 1 s=13+1 =14 n=1/10=0
                                Step 4- while(0)=> while(False) so loop will terminate






                                share|improve this answer













                                share|improve this answer




                                share|improve this answer



                                share|improve this answer










                                answered 8 hours ago









                                PRAKHAR GUPTAPRAKHAR GUPTA

                                133 bronze badges




                                133 bronze badges










                                • 2





                                  What are you getting at? It sounds like you're just restating the OP's case that while (n) is fine. Except, as they point out, it's equivalent to while (n != 0) not while (n > 0).

                                  – John Kugelman
                                  8 hours ago













                                • 2





                                  What are you getting at? It sounds like you're just restating the OP's case that while (n) is fine. Except, as they point out, it's equivalent to while (n != 0) not while (n > 0).

                                  – John Kugelman
                                  8 hours ago








                                2




                                2





                                What are you getting at? It sounds like you're just restating the OP's case that while (n) is fine. Except, as they point out, it's equivalent to while (n != 0) not while (n > 0).

                                – John Kugelman
                                8 hours ago






                                What are you getting at? It sounds like you're just restating the OP's case that while (n) is fine. Except, as they point out, it's equivalent to while (n != 0) not while (n > 0).

                                – John Kugelman
                                8 hours ago



















                                draft saved

                                draft discarded















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid


                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.

                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f58224638%2fmy-professor-says-my-digit-summing-code-is-flawed-is-he-right%23new-answer', 'question_page');

                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown









                                Popular posts from this blog

                                Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                                Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                                Ласкавець круглолистий Зміст Опис | Поширення | Галерея | Примітки | Посилання | Навігаційне меню58171138361-22960890446Bupleurum rotundifoliumEuro+Med PlantbasePlants of the World Online — Kew ScienceGermplasm Resources Information Network (GRIN)Ласкавецькн. VI : Літери Ком — Левиправивши або дописавши її