Search code examples
c++cmultiplicationnegative-number

Is there a functional difference between "x = -x" and "x *= -1" when negating values?


Code example:

float f = 123.456;
int i = 12345;
// negate by changing sign
i = -i;
f = -f;
// negate by multiplying with -1
i *= -1;
f *= -1.0f;

Apart from aesthetics, is there any factual reason why one should prefer one way over the other?

To me multiplication seems a little unnecessary. But I see the multiplication style more often, and wanted to hear if there's a good reason for it, besides preference.


Solution

  • Recommend to use what explains the code best, unless one is working with an old platform or compiler. In that case, use negation.

    Following are some obscure differences:

    int format with non-2's complement:
    In days of yore, a multiplication by of 0 and -1 could result in 0 yet a negation of 0 could result in -0. Of course 0 and -0 have the same value, yet different signs. Not all non-2's complement machines worked the same concerning this.

    Floating Point:
    Speed: A smart compiler will create efficient and likely the same code for f *= -1.0f and f *= -f. Yet a lesser compiler may not identify this equivalence and perform one slower than the other.

    Rounding: A negation need not invoke any rounding, yet a multiplication, even by 1.0, can involve a round. This happens in 2 cases: when the variables are of a higher precision (allowed in modern C, FLT_EVAL_METHOD) and in machines (more like relics) that performed their FP using base-16 rather than base-2. In this latter case, the precision wobbles (e.g IBM Floating Point) and a simple multiplication would present a rounded product. This behavior is uncommon these days.

    There also exist FP formats that have multiple representations for the same value, but a multiplication by 1 would return the preferred format, whereas negation would simply flip the sign bit. The results are the same value, but different bit patterns of the FP number.