Sign computation with a macro - algorithm

What the following expression computes, exactly?
#define SIGN(x) ((x < 0) ? -1 : (x > 0))
what yields if x is zero, less than zero, more than zero?
I guess I know the answer, but I'd like to check for clarity...
Thank you
EDIT: added missing parenthesis
EDIT: more info here

First, the macro doesn't compute anything. It is substituted into a source code, expanded, and the resulting text gets compiled. What the resulting text is, depends on the way you use the macro, especially on what parameter you give.
Second, the macro lacks one closing paren, so it probably would not give you a meaningful expression to be compiled.
Third, even when you add the lacking paren:
#define SIGN(x) ((x < 0) ? -1 : (x > 0))
it is possible you get unexpected results if you use the macro in a non-simplest way. For example,
SIGN(a ^ b)
would result in
((a ^ b < 0) ? -1 : (a ^ b > 0))
which is interpreted in C and C++ as
((a ^ (b < 0)) ? -1 : (a ^ (b > 0)))
which certainly is not what we intend.
You should add parentheses to avoid unwanted operators binding – for:
#define SIGN(x) (((x) < 0) ? -1 : ((x) > 0))
the above example will yield a sensible expression
(((a ^ b) < 0) ? -1 : ((a ^ b) > 0))
but that still doesn't protect you against unwanted double increment/decrement in case of plus-plus or minus-minus operators or double execution of a function in case the expression substituted for x contains a function call.

It does exactly what you probably think it does, gives -1 for negative numbers, 0 for zero, and 1 for positive numbers.
However, you should generally avoid function-like macros since they will not do what you expect if, for example, you try to calculate SIGN(value++). Since they're simple text substitutions, that would resolve to:
((value++ < 0) ? -1 : (value++ > 0)
You're far better off just using real functions and letting the compiler inline them if it decides it's worth it. You can also suggest to the compiler that inlining it, with the inline keyword, but keep in mind it is a suggestion.

That macro got a stray parenthesis.
It looks like it is meant to be an implementation of signum function, which returns -1, 1 or 0 depending on value of argument.
For sake of being safe and writing C++ code, it is prudent
to replace macro by template, similar to
template <class T>
int SIGN( T x )
{
return (x < T(0)) ? -1 : (x > T(0));
}
First comparision is argument of trenary operator ?:. Ternary would return -1 if expression evaluates to true , i.e. x is less than 0, otherwise it would return result of x > T(0).
That expression would evaluated to 0 if x equals to 0, otherwise it would be evaluated to 1.
Note that my implementation is not ideal, you can find better implementation elsewhere on SO.
An alternative expression can be:
return (T(0)<x) - (T(0)>x);
Which may be more effective with platforms that implement certain CPU instructions

If you use it with values only and not expressions that macro will produce -1, 0, 1, otherwise you may have serious problems. The tricky part is (x>0). Lets read the standard:
5.9 Relational operators [expr.rel]
The operators < (less than), > (greater than), <= (less than or equal
to), and >= (greater than or equal to) all yield false or true. The
type of the result is bool.
and
3.9.1 Fundamental types [basic.fundamental]
Values of type bool are either true or false. Values of type bool participate in integral promotions (4.5).
Thus x>0 is either true or false.
4.5 Integral promotions [conv.prom]
A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one.
and is promoted to either 1 or 0 (respectively).

Related

One and only one zero comparison with the least operations

This might be a silly question, but in some function I have two int s, and need to compare them to find if exactly one of them is ==0... Both of the ways I came up with require 5 logical operations, and I can't think of anything shorter... Is there a shorter way?
What I came up with is:
int x, y;
if (((x==0) || (y==0)) && (x != y)){} // most obvious option, or:
if (((x^y) == x) ^ ((x^y) == y)){} // looks better, but still 5 ops
The expression ((x^y) == x) ^ ((x^y) == y) can be simplified in a straightforward way.
(x^y) == x if and only if y == 0, and likewise (x^y) == y if and only if y == 0. So the following uses three operations to compute the condition:
if((x == 0) ^ (y == 0)) {
// ...
}
This makes sense because using XOR as a logical operator, the result is true if and only if one but not both of the operands is true. So this directly tests whether one but not both of x == 0 and y == 0 are true.

Why are "not greater/less" (e.g. "!>" or "!<") operators not used in most programming languages

I understand that you can get the same behavior by using <= or !(x > y) but I usually rather think in terms of not greater instead of less than or equal, so having something like !> and !< would actually be really neat to have for me and would match the != operator perfectly.
The !(x > y) syntax requires more characters and reads: not: x is greater than y, which is unhandy and very unlike natural speech.
I have never seen !< or !> operators anywhere, but have been wondering ever since I started programming why they are not supported. Are there any reasons why not?
Using the least number of logical and comparison operators, and those the most closest to classic math and logic makes it simpler to reason about conditions.
There were programming languages like Natural and COBOL with operators like NOT LESS THAN, but reasoning about (a !< b) when thinking over a complex condition is much more difficult than !(a < b), which is equivalent to (a >= b).
An example:
!(!(a < b) && !(a > c))
Is equivalent to:
!((a >= b) && (a <= c))
which translates to:
(a < b) || (a > c)
There's nothing to gain from !((a !< b) && (a !> c))?

How can I emulate the results of this if then then statement while using correct syntax?

Working on an exercise for university class and cant seem to represent what I am trying to do with correct syntax in ocaml. I want the function sum_positive to sum all the positive integers in the list into a single int value and return that value.
let int x = 0 in
let rec sum_positive (ls: int list) = function
|h::[] -> x (*sum of positive ints in list*)
|[] -> 0
|h::t -> if (h >= 0) then x + h then sum_positive t else sum_positive t (*trying to ensure that sum_positive t will still run after the addition of x + h*)
On compiling I am met with this error,
File "functions.ml", line 26, characters 34-38:
Error: Syntax error
This points to the then then statement I have in there, I know it cannot work but I cant think of any other representations that would.
You have if ... then ... then which is not syntactically valid.
It seems what you're asking is how to write what you have in mind in a way that is syntactically valid. But it's not clear what you have in mind.
You can evaluate two expressions in OCaml sequentially (one after the other) by separating them with ;. Possibly that is what you have in mind.
However it seems to me your code has bigger problems than just syntax. It appears you're trying to use x as an accumulated sum for the calculation. You should be aware that OCaml variables like x are immutable. Once you say let x = 0, the value can't be changed later. x will always be 0. The expression x + h doesn't change the value of x. It just evaluates to a new value.
The usual way to make this work is to pass x as a function parameter.
I was getting an issue that had involved the parameter of , I believe it was because I was trying to add an int value to function of type int list. This is what I ended up with.
let rec sum_positive = function
|[] -> 0
|h::t -> if h > 0 then h + (sum_positive t) else sum_positive t
a lot simpler than I thought it out to be.

Understanding precedence of assignment and logical operator in Ruby

I can't understand precedence of Ruby operators in a following example:
x = 1 && y = 2
Since && has higher precedence than =, my understanding is that similarly to + and * operators:
1 + 2 * 3 + 4
which is resolved as
1 + (2 * 3) + 4
it should be equal to:
x = (1 && y) = 2
However, all Ruby sources (including internal syntax parser Ripper) parse this as
x = (1 && (y = 2))
Why?
EDIT [08.01.2016]
Let's focus on a subexpression: 1 && y = 2
According to precedence rules, we should try to parse it as:
(1 && y) = 2
which doesn't make sense because = requires a specific LHS (variable, constant, [] array item etc). But since (1 && y) is a correct expression, how should the parser deal with it?
I've tried consulting with Ruby's parse.y, but it's so spaghetti-like that I can't understand specific rules for assignment.
Simple. Ruby only interprets it in a way that makes sense. = is assignment. In your expectation:
x = (1 && y) = 2
it does not make sense to assign something to 1 && y. You can only assign something to a variable or a constant.
And note that the purpose of the precedence rule is to disambiguate an otherwise ambiguous expression. If one way to interpret it does not make sense, then there is no need for disambiguation, and hence the precedence rule would not be in effect.
My understanding is that in the case of
x = 1 && y = 2
The logical AND is parsed first. The AND then is forced to evaluate its left side and its right side. In the evaluation the left side the first assignment occurs, and then in the evaluation of the right side the second does the same. It is for this reason that in the case of:
x = false && y = 2
"y" will never be assigned. The AND is hit, forcing the x assignment to evaluate, but never bothering to run the y assignment, as it is unnecessary for the AND to fulfill its purpose.
In other words, the parser is, again, simply to my understanding, smart enough to recognize that in running the AND the equation is split into a left and right side (equations), which are in turn evaluated according to the order of operation.

Evaluation functions and expressions in Boolean expressions

I am aware how we can evaluate an expression after converting into Polish Notations. However I would like to know how I can evaluate something like this:
If a < b Then a + b Else a - b
a + b happens in case condition a < b is True, otherwise, if False a - b is computed.
The grammar is not an issue here. Since I only need the algorithm to solve this problem. I am able evaluate boolean and algebraic expressions. But how can I go about solving the above problem?
Do you need to assign a+b or a-b to something?
You can do this:
int c = a < b ? a+b : a-b;
Or
int sign = a < b ? 1 : -1;
int c = a + (sign * b);
Refer to LISP language for S-express:
e.g
(if (> a b) ; if-part
(+ a b) ; then-part
(- a b)) ; else-part
Actually if you want evaluate just this simple if statement, toknize it and evaluate it, but if you want to evaluate somehow more complicated things, like nested if then else, if with experssions, multiple else, variable assignments, types, ... you need to use some parser, like LR parsers. You can use e.g Lex&Yacc to write a good parser for your own language. They support somehow complicated grammars. But if you want to know how does LR parser (or so) works, you should read into them, and see how they use their table to read tokens and parse them. e.g take a look at wiki page and see how does LR parser table works (it's something more than simple stack and is not easy to describe it here).
If your problem is just really parsing if statement, you can cheat from parser techniques, you can add empty thing after a < b, which means some action, and empty thing after else, which also means an action. When you parsed the condition, depending on correctness or wrongness you will run one of actions. By the way if you want to parse expressions inside if statement you need conditional stack, means something like SLR table.
Basically, you need to build in support for a ternary operator. IE, where currently you pop an operator, and then wait for 2 sequential values before resolving it, you need to wait for 3 if your current operation is IF, and 2 for the other operations.
To handle the if statement, you can consider the if statement in terms of C++'s ternary operator. Which formats you want your grammar to support is up to you.
a < b ? a + b : a - b
You should be able to evaluate boolean operators on your stack the way you currently evaluate arithmetic operations, so a < b should be pushed as
< a b
The if can be represented by its own symbol on the stack, we can stick with '?'.
? < a b
and the 2 possible conditions to evaluate need to separated by another operator, might as well use ':'
? < a b : + a b - a b
So now when you pop '?', you see it is the operator that needs 3 values, so put it aside as you normally would, and continue to evaluate the stack until you have 3 values. The ':' operator should be a binary operator, that simply pushes both of its values back onto the stack.
Once you have 3 values on the stack, you evaluate ? as:
If the first value is 1, push the 2nd value, throw away the third.
If the first value is 0, throw away the 2nd and push the 3rd.

Resources