Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 952
LearnCocos2D Avatar asked May 27 '15 13:05

LearnCocos2D


People also ask

What does N&1 mean?

n&1 performing a binary AND between n and 1. if (n&1) is checking for whether a number is odd, since odd numbers will have LSB of 1 and even numbers don't.

What does |= mean in CPP?

| is bitwise OR operation. |= just assigns the bitwise OR of a variable with another to the one on the LHS.

What does <= mean in Python?

Less than or equal to.

What does the &= operator do?

The &= operator concatenates the String expression on its right to the String variable or property on its left, and assigns the result to the variable or property on its left.


2 Answers

Based on my answer to “fastest-way-to-negate-a-number”

Speed

The answers to a similar question have indicated that:

  • You should forget about speed and choose the idiom that you find most readable.
  • Almost all compilers generate equivalent optimal code (probably a single instruction) for anything like a = -a, a *= -1 etc.
    • But though MSVS 2012 (optimised?) uses one instruction for each, they take 1 cycle for = -a and 3 for *= -1.
  • Any attempt to make it faster will make it far less readable and could easily make it slower.
  • If you need to optimise, you should start by analysing generated code and performance.

Side-effects and irredundancy

There is however a practical advantage to the *= -1 idiom: you only have to write the left hand side once, and it is only evaluated once. This is relevant when the LHS is long, complex or expensive or may have side-effects:

(valid ? a : b)[prime_after(i++)] *= -1;
*look_up (input) *= -1;  // Where look_up may have side-effects
parity[state][(unsigned int)getc(stdin)] *= -1;
variable_with_a_long_explanatory_name *= -1;

A further advantage of this irredundancy is that when seeking a bug one can be certain that the number really is being negated in situ, and that there is no subtle difference in the two expressions.

Once one has adopted an idiom, one tends to stick with it in other situations, so it is understandable to stick to *= -1.

like image 139
PJTraill Avatar answered Oct 13 '22 23:10

PJTraill


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.

like image 41
chux - Reinstate Monica Avatar answered Oct 13 '22 23:10

chux - Reinstate Monica