Kenneth Brody said:
Mathematically, "(a+b)-b" is the same as "a". Of course, in this
case, there may be a loss of precision, but does the standard say
that you must preserve loss of precision? Why doesn't the "as if"
rule apply to floating point?
Your error is in your first line.
Mathematically, "(a+b)-b" means whatever you want it to mean.
You can -choose- to interpret it as a statement involving
variables and operators, but there is no -inherent- meaning
in using an operator named "+" or "-", so the operators can be
given any interpretation. In logic, an "operator" is a function
in the mathematical sense of "function", which is to say an arbitrary
mapping from input tuples to output tuples. The mapping described
by any particular "function" (and thus by any particular operator)
need not make any -sense- -- it just *is*. Some mappings are amenable
to being described more easily than just the exhaustive list of
input and output tuples, but it is an error to -assume- that
when you see operators "+" or "-" that those operators are definitely being
used in the sense of a function mapping that has any kind of sensible
or compact description.
For example, it would be perfectly valid to use a mathematic model
in which (a+b)-b was to be interpreted as NAND(XOR(a,b),b) -- which
would, incidently, interpret "(a+b)-b" as mapping to "true" if a is false.
Thus, when you read "(a+b)-b" in a C program, you should not be
automatically interpreting this as algebraic addition and subtraction.
Operations on signed integers need not obey standard algebraic rules
in C (because a+b might overflow in signed integers, and the result
of overflowing signed integers is not specified in C.) Operations on
floating point numbers usually do not obey standard algebraic rules in C.
Even with unsigned integers, do not expect standard algebraic rules:
(a/b)*b is not a unless b is non-zero and a is an exact integral
multiple of b.