# C 89 Implementation-Defined Behavior?

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 04-17-2010
billhavens
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.

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....
• 04-17-2010
tabstop
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.)
• 04-17-2010
billhavens
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
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.)

• 04-17-2010
tabstop
Rounding down. Not rounding to nearest.
• 04-17-2010
grumpy
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.
• 04-17-2010
billhavens
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
Rounding down. Not rounding to nearest.

• 04-17-2010
tabstop
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).
• 04-17-2010
grumpy
Quote:

Originally Posted by billhavens
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).
• 04-17-2010
billhavens
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
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).

• 04-17-2010
tabstop
Quote:

Originally Posted by billhavens
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.
• 04-17-2010
billhavens
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
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.

• 04-17-2010
tabstop
Quote:

Originally Posted by billhavens
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.
• 04-17-2010
billhavens
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
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.

• 04-17-2010
billhavens
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
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?

• 04-17-2010
tabstop
Quote:

Originally Posted by billhavens
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.
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last