5
if (abs(u) > Vdc)
    u = Vdc*((u > 0) - (u < 0));

This code is in C considering we enter the if condition what will happen ? Vdc = 24; consider any arbitrary value of u for an explanation

Dhruv
  • 645
  • 9
  • 17
  • It's an implicit type conversion from bool to an integer. You see, u will always be positive and may be greater than Vdc. U ends up being equal to Vdc * (1 (true) - 0)). Effectively, it's a longhand version of u = Vdc. – Poriferous Apr 08 '15 at 18:27
  • @Poriferous that is not true. u can be negative (assuming it is declared as a signed int). – mstbaum Apr 08 '15 at 18:29
  • Certainly `u` better be an `int` or narrower signed integer, else `abs(u)`, which returns an `int`, is a problem. `u == INT_MIN` is a problem. Code using `if (u > Vdc) u == Vdc else if (u < -Vdc) u = -Vdc;` would be clearer - _maybe_ not as fast. – chux - Reinstate Monica Apr 08 '15 at 19:04
  • abs(u) means u will ALWAYS be positive; it's the absolute value. The if statement is therefore always true. Because u is always greater than 0 (always positive) it will always be 1 as a result. However this is not the case with u < 0, therefore that part of the statement is 0. 1 - 0 = 1; therefore u = Vdc * 1, and is therefore the entire code is equivalent to u = Vdc. Whether the integer is signed or not is irrelevant; it's always positive. – Poriferous Apr 08 '15 at 23:37

4 Answers4

8

If u > 0 the statement will become 1 - 0 (true - false) = 1. If u < 0 it will become -1. If it is zero, it will become 0 as well. So basically it is returning the "sign" of u (or more precisely 1 with corresponding sign). The overall code snippet is for clamping u between +Vdc and -Vdc. (As suggested, it will work only for positive Vdc).

Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61
  • 1
    The caveat worth noting is that `Vdc` would have to be positive for this to be true. If `Vdc` were negative, `u` would fall in the set of all real numbers. – mstbaum Apr 08 '15 at 18:34
  • Note that clamping may not occur if `u == INT_MIN` due to `abs(u)` may return a negative value. – chux - Reinstate Monica Apr 08 '15 at 18:56
  • and actually I would like to amend my comment. If `Vdc` were negative, then `u` could only equal +/-`Vdc` after this snippet – mstbaum Apr 08 '15 at 18:57
  • @mstbaum It is still valid comment, since the code is obviously not designed for such a scenario – Eugene Sh. Apr 08 '15 at 18:58
  • @chux: That's UB, not a negative value. GCC optimizes `if(abs(x) < 0)` to `if(0)`, for example. – mafso Apr 08 '15 at 20:52
  • @mafso True that `int(INT_MIN)` could be undefined behavior C11 7.22.6.1 2. A common undefined behavior result is that `int(INT_MIN)` returns `INT_MIN` : a negative value. IAC, `abs(INT_MIN)` is a problem. – chux - Reinstate Monica Apr 08 '15 at 21:07
  • @chux: As illustrated with `if(abs(x) < 0)`, Gcc makes use of that UB and assumes `INT_MIN` is never passed to `abs` (tested with 4.7.2 and 4.9.2). Though I'm not sure if I got what you're saying; what is "IAC"? – mafso Apr 08 '15 at 21:15
5

The expression in parentheses is the sign function. If u > 0 holds, the expression becomes

(u > 0) - (u < 0) -> 1 - 0 -> 1

because the first condition is true and the second is false. Same for the u < 0 case.

VHarisop
  • 2,816
  • 1
  • 14
  • 28
2

This is a technique to model the function

    |0,  if u = 0
 f= |1,  if u > 0
    |-1, if u < 0

It avoids using an if clause to do this comparison, and evaluates like so

//For positive values of u 
(u>0) - (u<0) = 1 - 0 = 1
//For negative values of u
(u>0) - (u<0) = 0 - 1 = -1
//For u = 0
(u>0) - (u<0) = 0 - 0 = 0
gibertoni
  • 1,368
  • 12
  • 21
2

This is mathematical function Sign it's value is

  1. 1 if u > 0
  2. 0 if u = 0
  3. -1 if u < 0

this is how it works:

as per C standard section 6.5.8 relational operators

shall yield 1 if the specified relation is true and 0 if it is false. The result has type int.

now if u is greater than 0 then u > 0 returns 1 and u < 0 returns 0. 1-0 is 1, e.g. any u greater than 0 converted to 1. Similarly, any u less than 0 is converted into -1.

fukanchik
  • 2,811
  • 24
  • 29