This is a challenge I have come up with; however, I do not know the answer: I am asking for it. Note that there is no prize besides the intellectual gain.
Here it is:
For any arbitrary number (float, negative, etc.), logically negate it using math.
i.e. If my input to your program/function is 500, I should get 0. Successive calls should return 1, then 0, then 1, etc. As mentioned above, it must also work for negative and floating-point numbers.
Restrictions:
No conditionals. Only math. (add, subtract, divide, multiply, maybe modulus). You may use some functions, such as abs().
No exclamation point (!).
It must be one single equation.
You may not use variables besides the input.
No storing data in non-volatile memory for the next program iteration.
I'm just wondering whether or not this is possible, or if ! is the only way.
I did come up with this so far:
output = 1 + (-1) * input
but it only works if the inputs are 1 or 0... not for floats or negative numbers or high numbers like 129.
"So if input is 500 (111110100) then 500<<2 = 2000, 2000+1 = 2001"
No, I had <<32, not 2.
unsigned long is 32, so any number shifted left 32 bits would always be 0, and adding 1 would yield 1.
More of a joke answer
I could have said
output = input *0 + 1; for the same.
What's the point of this exercise baum?
Will the "successive calls" be the output from the first call, or a newly inputted #?
For any arbitrary number (float, negative, etc.), negate it using math.
i.e. If my input to your program/function is 500, I should get 0. Successive calls should return 1, then 0, then 1, etc. As mentioned above, it must also work for negative and floating-point numbers.
What? I thought negation meant make negative, e.g. 500 becomes -500
And I don't see how you can use just math (conditional logic) to get two different answers from the same input.
Crossroads: sorry, i meant to type "32." but 500<<32 would overflow, would it not? It should return 0, much like the '!' operator. (the function should work for ALL successive calls)
What's the point of this exercise baum?
It's a programming exercise. And "successive calls" could be any number. It could be the output from the last call, or a new number. Either one.
dc42: Here is a truth table:
INPUT OUTPUT
0,0.0 1 <-- zero returns 1
anything else 0 <-- all else returns 0, includes negatives, floats, etc.
WizendEE:
sorry... should have said logical negation. I will edit the original. Think of the function to operate like '!'
"You may not use variables besides the input.
No storing data in non-volatile memory for the next program iteration."
vs
"And "successive calls" could be any number. It could be the output from the last call,"
How would one do that without storing the prior output somewhere?
You may not store anything from within the function. You could write a program that called your function many times, but the function itself can not use any variables, etc. from within.
Find a way to implement the logical NOT command (!) with only addition, subtraction, multiplication, division, and absolute value. It must work with signed and unsigned integers and floats.
The negative part is pretty easy; just absolute value it.
for ints, longs and the IEE754 float the value 0 are bitwise all 0's.
Solution to the problem is to OR up all individual bits and subtract the "or-sum" from 1 : only bitmath and one subtraction;
something like this?
void setup()
{
Serial.begin(115200);
int y = func(0.0);
Serial.println(y);
y = func(1.0);
Serial.println(y);
y = func(-10.0);
Serial.println(y);
}
// only a type declaration outside the function, no memory :)
union U
{
unsigned long x;
float f;
};
int func(float f)
{
U u;
u.f = f;
int rv = 0;
for (int i=0; i<32; i++)
{
rv |= bitRead(u.x, i);
}
return 1-rv;
}
void loop(){}
Note the loop can be unrolled to one expression see below
Looks pretty good. But what if I have an arbitrary data type, too? A byte, for example, wouldn't work with your function. So without using something like a template, can it be done with a single, one-line function that works for all real numbers? (It's really more of a math problem than a CS/programming question...)
baum
p.s. I think I have an idea... It involves the sign() function, which is not commonly used in mathematics (but it is allowed here, as are other math functions... sin, cos, tan, etc.) Also, the sign() function can be (sort of) represented by abs(x)/x (but it doesn't work for zero). That is your hint. Maybe a graph of the sign function will help.