Thread: C 89 Implementation-Defined Behavior?

  1. #16
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by billhavens View Post
    Your statement implies that rounding to the nearest is not repeatable.
    I said no such thing. What you are not realising is that microprocessor design involves trade-offs between competing requirements. Mathematical fidelity of basic operations (eg integer division rounding to nearest, rather than up or down) is not a primary design constraint in microprocessor design.

    You are assuming there are no trade-offs in microprocessor design. In reality, repeatability of microprocessor behaviour is statistical: there is a likelihood that any operation will not behave correctly, because (in modern processors) effects like voltage variations within a circuit and other random effects. The speed of an instruction tends to go down as the number of circuit elements (resistors, capacitors, transistors, etc) used to implement that instruction goes up. The number of components needed to implement a "round up" or "round down" integer division circuit is much less than the number needed to implement a "round to nearest" circuit.

    Because of things like this, even in modern microprocessor design, basic operations tend to be implemented in as simple a form as possible to maximise performance. Techniques are also used that reduce likelihood of a circuit being subjected to some variation that causes it to produce erroneous results. Those sorts of trade-offs tend to discourage hardware designers from implementing operations (eg integer division) in a more costly (i.e. demanding more physical circuit components) manner.

    Quote Originally Posted by billhavens View Post
    So in doing a little thinking I like the C99 standard MUCH better.
    It offers consistency. However, it also broke one of the mandatory design constraints that guided development of the 1989 C standard. A requirement of the 1989 C standard was that any given operation could be implemented in a way that was most efficient on all possible hardware platforms. That meant that simple operations (eg integer division) could be implemented in few machine instruction. That meant allowing use of native instructions.

    Some microprocessors in 1989 supported "round up" integer division when given negative operands. Some others supported "round down". Very few - none as far as I know - supported "round to nearest". The 1989 C standard had to allow "implementation defined" in order to allow maximum efficiency on all possible hardware.
    Last edited by grumpy; 04-18-2010 at 04:32 AM.
    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.

  2. #17
    Registered User
    Join Date
    Apr 2010
    Posts
    8
    I am trying not to assume anything as I have stated a couple of times I really don't know at all what the CPU designers have to work with. That being said I guess I do have some assumptions as to how I think things should work based on the arithmetic that I have been taught so far.

    Based on what you were saying about the C89 standard though and how it was more flexible with different CPUs and such... in the example of 5 % 2 if there was a CPU that decided that 5 / 2 was 3 rather than 2 then the MOD answer would be -1 rather than 1 which I would deem 1 the correct answer and -1 to be wrong. I would also suggest that this is one of the reasons that the C99 group decided to implement the round towards 0 rather than allow for two competing standards.

    As I stated in an earlier post I always viewed math as being "fairly" static in that 2 + 2 is always 4 not 5 and I would view the above MOD the same way. I understand in higher level math you can get multiple answers but again you would always get the "same" multiple answers. I totally get what you are saying about the "trade offs" they make when designing. Is there a way to code in c89 to make sure that you ALWAYS get the "usual" or "expected" answer? I am sure that there will be things in C99 that seem this way to me as well....

    Here is my question though...say you make a C99 compiled program and it runs on one of those CPUs that they chose to round away from 0 contrary to the C99 standard what would happen?

    Thanks,
    Bill

    Quote Originally Posted by grumpy View Post
    I said no such thing. What you are not realising is that microprocessor design involves trade-offs between competing requirements. Mathematical fidelity of basic operations (eg integer division rounding to nearest, rather than up or down) is not a primary design constraint in microprocessor design.

    You are assuming there are no trade-offs in microprocessor design. In reality, repeatability of microprocessor behaviour is statistical: there is a likelihood that any operation will not behave correctly, because (in modern processors) effects like voltage variations within a circuit and other random effects. The speed of an instruction tends to go down as the number of circuit elements (resistors, capacitors, transistors, etc) used to implement that instruction goes up. The number of components needed to implement a "round up" or "round down" integer division circuit is much less than the number needed to implement a "round to nearest" circuit.

    Because of things like this, even in modern microprocessor design, basic operations tend to be implemented in as simple a form as possible to maximise performance. Techniques are also used that reduce likelihood of a circuit being subjected to some variation that causes it to produce erroneous results. Those sorts of trade-offs tend to discourage hardware designers from implementing operations (eg integer division) in a more costly (i.e. demanding more physical circuit components) manner.


    It offers consistency. However, it also broke one of the mandatory design constraints that guided development of the 1989 C standard. A requirement of the 1989 C standard was that any given operation could be implemented in a way that was most efficient on all possible hardware platforms. That meant that simple operations (eg integer division) could be implemented in few machine instruction. That meant allowing use of native instructions.

    Some microprocessors in 1989 supported "round up" integer division when given negative operands. Some others supported "round down". Very few - none as far as I know - supported "round to nearest". The 1989 C standard had to allow "implementation defined" in order to allow maximum efficiency on all possible hardware.

  3. #18
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by billhavens View Post
    Based on what you were saying about the C89 standard though and how it was more flexible with different CPUs and such... in the example of 5 % 2 if there was a CPU that decided that 5 / 2 was 3 rather than 2 then the MOD answer would be -1 rather than 1 which I would deem 1 the correct answer and -1 to be wrong. I would also suggest that this is one of the reasons that the C99 group decided to implement the round towards 0 rather than allow for two competing standards.
    C89 did not allow for such flexibility. You had two choices: always round down, or always truncate. For positive values, these two give the same answer. Round to nearest was never an option.

    Quote Originally Posted by billhavens View Post
    Here is my question though...say you make a C99 compiled program and it runs on one of those CPUs that they chose to round away from 0 contrary to the C99 standard what would happen?

    Thanks,
    Bill
    If a system is developed for a CPU with native division that rounds down instead of truncates, then the C99 compiler must not generate code that uses that native instruction (unless it can guarantee the values are positive), but must instead do the division "manually" (i.e., generate code to do the "proper" division itself, rather than using the built-in).

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