Thread: C 89 Implementation-Defined Behavior?

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    8

    C 89 Implementation-Defined Behavior?

    I am a first semester C programming student with pretty much no experience but a good head for logic...anyway here is my confusion:

    I am reading K.N. Kings "C Programming" Second Edition. Anyways on page 55 he discusses Implementation-Defined Behavior and has this to say:

    "Some CPUs yield -1 when -9 is divided by 7, while others produce -2; the C89 standard simply reflects this fact of life." K.N. King

    Now in standard arithmetic -9 / 7 = -1.2857142857142857142857142857143

    When rounding, as I would assume the CPU would be doing in this instance, assuming that -9 and 7 are stored in integers how could anyone program a CPU to make this -2?

    If it is not rounding but rather truncating from what I understand happens it would simply be -1. I have some other math related questions that just simply do not make any sense to me whatsoever yet but I will wait until I thoroughly understand this one.

    Thanks for your time,
    Bill

    p.s. As I understand it in C99 this would always come out to -1 being that the decimal is truncated if you are not using floats or better. This makes sense to me....

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    C89 did not specify whether the division would be truncated (-1) or rounded down to the next lowest integer (-2). (For positive results, either one gives the same answer.)

    (EDIT: And as to why, rounding down means that % would always give a positive remainder between 0 and the divisor (if the divisor was positive). In C99, -9%7 is now -2.)

  3. #3
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    This might seem silly but I was always taught that when rounding that 0-4 you go towards 0 and 5-9 you go towards the next number...

    So when rounding why not since it is 1.2 go to 1.... how can they say go to 2? I still don't understand?

    Thanks,
    Bill

    Quote Originally Posted by tabstop View Post
    C89 did not specify whether the division would be truncated (-1) or rounded down to the next lowest integer (-2). (For positive results, either one gives the same answer.)

    (EDIT: And as to why, rounding down means that % would always give a positive remainder between 0 and the divisor (if the divisor was positive). In C99, -9%7 is now -2.)

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Rounding down. Not rounding to nearest.

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    It's not rounding.

    If the mathematical result of an integral division between two integral values, then real CPUs either pick the value that is greater or pick the one that is lesser.

    With negative operands, some CPUs pick the next greater, some pick the next lesser. Which means it either truncates towards zero or goes away from zero. So the 1989 C standard simply stated it is implementation defined which happens.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    But that is less accurate!!!

    I guess my problem is that I had this grandiose concept in my mind that computers were VERY accurate... what you put in was what you get out. That concept is getting shaken up a bit and I don't like it...snicker.

    Thanks,
    Bill

    Quote Originally Posted by tabstop View Post
    Rounding down. Not rounding to nearest.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Even for positive numbers, it will go down and not to nearest, but people are more used to it (i.e. 26 div 7 is 3 remainder 5, and / and % will give you those numbers respectively).

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by billhavens View Post
    But that is less accurate!!!

    I guess my problem is that I had this grandiose concept in my mind that computers were VERY accurate... what you put in was what you get out. That concept is getting shaken up a bit and I don't like it...snicker.
    You're mixing up the notions of repeatability and accuracy.

    When given a choice (or forced to choose) computer hardware designers aim for repeatability and performance at the expense of accuracy. If software designers care about mathematical accuracy - and not all do - then they have to ensure it (usually at the expense of increasing number of instructions needed).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  9. #9
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    Your statement implies that rounding to the nearest is not repeatable. Anything with a standard rule such as round to nearest is repeatable and in this instance more accurate so why not chose to do both? Still does not make any sense to me.

    I understand the facts about how it works but I disagree with how they chose to make it work with my limited understanding at this point with what they have to work with.

    Bill

    Quote Originally Posted by grumpy View Post
    You're mixing up the notions of repeatability and accuracy.

    When given a choice (or forced to choose) computer hardware designers aim for repeatability and performance at the expense of accuracy. If software designers care about mathematical accuracy - and not all do - then they have to ensure it (usually at the expense of increasing number of instructions needed).
    Last edited by billhavens; 04-17-2010 at 07:07 PM.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by billhavens View Post
    Your statement implies that rounding to the nearest is not repeatable. Anything with a standard rule such as round to nearest is repeatable and in this instance more accurate so why not chose to do both? Still does not make any sense to me.

    I understand the facts about how it works but I disagree with how they chose to make it work with my limited understanding at this point with what they have to work with.

    Bill
    You appear to be assuming that information about the remainder is available while doing integer division, or at least in its decimal approximation. That doesn't have to be true; if the division is done by shifts&subtracts, then the remainder will be left over in the other register, but no one is going to bother doing a comparison between twice the remainder and the divisor to see whether to add one more, as I would expect that would add significantly to the total time to take the division.

  11. #11
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    Well as I stated I do have a limited understanding of what they have to work with and as such I have NO idea what "shifts&subtracts" means yet. Anyway I have gotten a better understanding of how C89 did that so onto my next question:

    OK so here he says "If i or j is negative, the sign of i % j in C89 depends on the implementation. (For example, the value of -9 % 7 could be either -2 or 5).

    I am assuming that the 5 is a typo and should be 2?

    On my scientific calculator when I do MODs if the first number is - then the answer is - and if the second number is - then the answer is positive. This I believe is the way C99 works it whereas in C89 it could be - or + in either case? Can someone explain this a little?

    Thanks,
    Bill

    Quote Originally Posted by tabstop View Post
    You appear to be assuming that information about the remainder is available while doing integer division, or at least in its decimal approximation. That doesn't have to be true; if the division is done by shifts&subtracts, then the remainder will be left over in the other register, but no one is going to bother doing a comparison between twice the remainder and the divisor to see whether to add one more, as I would expect that would add significantly to the total time to take the division.

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by billhavens View Post
    Well as I stated I do have a limited understanding of what they have to work with and as such I have NO idea what "shifts&subtracts" means yet. Anyway I have gotten a better understanding of how C89 did that so onto my next question:

    OK so here he says "If i or j is negative, the sign of i % j in C89 depends on the implementation. (For example, the value of -9 % 7 could be either -2 or 5).

    I am assuming that the 5 is a typo and should be 2?

    On my scientific calculator when I do MODs if the first number is - then the answer is - and if the second number is - then the answer is positive. This I believe is the way C99 works it whereas in C89 it could be - or + in either case? Can someone explain this a little?

    Thanks,
    Bill
    This is the point I made earlier: if you go with C99 mode the result of the division is -1 and the remainder is -2, because (-1)*7 + -2 = -9. If you go with the other mode that was allowed in C89, you could have the result of the division be -2 with a remainder of 5, because (-2)*7 + 5 = -9. In all cases, when dividing a/b, you will find that

    quotient * b + remainder = a.

  13. #13
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    I guess I just don't get the math yet...I will have to chew on it for a bit. I think that I have seen this example before as well. Anyway thanks again for your help and time and I look forward to getting much more into this all.

    Bill

    [EDIT] - Ok so I think the part that I did not get about your reconstructed versions of the equation was why put the -2 there in the first place but I think I understand now that the CPU in those cases simply truncates the fractional part of the answer and just rounds away from 0 rather than towards 0 which once the answer of the division is shown to be -2, 5 must be the remainder to get back to -9?

    Quote Originally Posted by tabstop View Post
    This is the point I made earlier: if you go with C99 mode the result of the division is -1 and the remainder is -2, because (-1)*7 + -2 = -9. If you go with the other mode that was allowed in C89, you could have the result of the division be -2 with a remainder of 5, because (-2)*7 + 5 = -9. In all cases, when dividing a/b, you will find that

    quotient * b + remainder = a.
    Last edited by billhavens; 04-17-2010 at 08:03 PM.

  14. #14
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    So in doing a little thinking I like the C99 standard MUCH better. As you stated earlier tabstop (which I did not completely understand when you said it) that 5 % 2 should be 2 with a mod of 1. If it rounded nearest, being that it is 2.5, up to 3 like what I was saying earlier then the mod would be -1 which would not be correct as far as basic arithmetic goes?

    Thanks,
    Bill

    Quote Originally Posted by billhavens View Post
    I guess I just don't get the math yet...I will have to chew on it for a bit. I think that I have seen this example before as well. Anyway thanks again for your help and time and I look forward to getting much more into this all.

    Bill

    [EDIT] - Ok so I think the part that I did not get about your reconstructed versions of the equation was why put the -2 there in the first place but I think I understand now that the CPU in those cases simply truncates the fractional part of the answer and just rounds away from 0 rather than towards 0 which once the answer of the division is shown to be -2, 5 must be the remainder to get back to -9?

  15. #15
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by billhavens View Post
    So in doing a little thinking I like the C99 standard MUCH better. As you stated earlier tabstop (which I did not completely understand when you said it) that 5 % 2 should be 2 with a mod of 1. If it rounded nearest, being that it is 2.5, up to 3 like what I was saying earlier then the mod would be -1 which would not be correct as far as basic arithmetic goes?

    Thanks,
    Bill
    What we have matches the "usual" arithmetic from way back when, yes.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  2. Trouble with multiple symbols
    By Kotatsu in forum C++ Programming
    Replies: 3
    Last Post: 04-08-2003, 09:03 PM
  3. Pure virtual implementation, or not.
    By Eibro in forum C++ Programming
    Replies: 2
    Last Post: 03-19-2003, 08:05 PM
  4. Header files
    By borland_man in forum C++ Programming
    Replies: 14
    Last Post: 02-22-2002, 04:30 AM
  5. Function basics
    By sjleonard in forum C++ Programming
    Replies: 15
    Last Post: 11-21-2001, 12:02 PM