Define a function sign which given an integer returns 1 if it is positive, -1 if it is negative and 0 if it is zero.
my solutions
solution 1
let sign i = if i!=0 then (if i<0 then -1 else 1) else 0;;
solution 2
let sign x =
if x = 0 then 0 else
if x<0 then -1 else 1;;
It doesn't work for negative numbers but it works for positive numbers and zero.
I receive the following error
Error: This expression has type int -> int
but an expression was expected of type int
As noted in comments, your functions look correct.
You are most likely calling it as: sign -1 which is parsed as (sign) - (1). Thus the compiler complaint that a function was encountered where an expression of type int was expected.
This can be overcome in two ways. Using parens to disambiguate, or using the ~- prefix.
sign (-1)
sign ~-1
As an additional note, this can also be implemented in terms of a comparison to 0.
let sign n = compare n 0
Or if you're of a slightly more Haskell-y mindset.
let sign = Fun.flip compare 0
As a further aside, I would suggest the following style:
let sign x =
if x = 0 then 0
else if x<0 then -1
else 1
As opposed to:
let sign x =
if x = 0 then 0 else
if x<0 then -1 else 1
Related
int64_t lstbt(int64_t val){
int64_t msk = val&(val-1);
return log2(val^msk);
}
What does the msk actually computes, and why are we returning log of value xor msk?
To understand the function:
int64_t lstbt(int64_t val){
int64_t msk = val&(val-1);
return log2(val^msk);
}
let us break it into smaller chunks.
First the statement val-1, by adding -1 to val, you flip (among others) the least significant bit (LSB), (i.e., 0 turns into 1, and vice-versa).
The next operation (val&(val-1)) applies an "and" bitwise. From the & operator we know that:
1 & 1 -> 1
1 & 0 -> 0
0 & 1 -> 0
0 & 0 -> 0
So either
val was initially ...0, and val - 1 is ....1, and in this case val&(val-1) produces ...0;
or var was initially ...1, and var - 1 is ....0, and in this case val&(val-1) produces ...0;.
So in both cases, val&(val-1) set to 0 the LSB of var. Besides that, another important change that val&(val-1) does is setting to 0 the first rightmost bit set to 1.
So let us say that val = xxxxxxxx10000 (it could have been xxxxxxxxx1000 as long as it showcases the right most bit set to 1), when msk=val&(val-1) then msk will be xxxxxxxx00000
Next, we have val ^ msk; a XOR bitwise operation, which we know that:
1 ^ 1 -> 0
1 ^ 0 -> 1
0 ^ 1 -> 1
0 ^ 0 -> 0
So because val will be something like xxxxxxxx10000 and msk xxxxxxxx00000, where the bits represented with 'x' from val will match exactly those from msk; the result of val ^ msk will always be a number with all bits set to 0 with exception for the only bit that will be different between val and msk, namely the right most bit set to 1 of val.
Therefore, the result from val ^ msk will always be a value that is a power of 2 (except when val is 0). A value that can be represent by 2^y = x, where y is the index of the right most bit set to 1 in val, and x is the result from val^msk. Consequently, log2(val^msk) gives back y i.e., the index of the right most bit set to 1 in val.
val&(val-1) # to figure out if value is either 0 or an exact power of two.
val^msk # cuts the part of power of 2 from val
log2 # finds the index of bit which set val^msk.
so i guess the function you have lstbt is to find out how many times the val can divide on 2 with reminder 0.
Why is X % 0 an invalid expression?
I always thought X % 0 should equal X. Since you can't divide by zero, shouldn't the answer naturally be the remainder, X (everything left over)?
The C++ Standard(2003) says in §5.6/4,
[...] If the second operand of / or % is zero the behavior is undefined; [...]
That is, following expressions invoke undefined-behavior(UB):
X / 0; //UB
X % 0; //UB
Note also that -5 % 2 is NOT equal to -(5 % 2) (as Petar seems to suggest in his comment to his answer). It's implementation-defined. The spec says (§5.6/4),
[...] If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
This answer is not for the mathematician. This answer attempts to give motivation (at the cost of mathematical precision).
Mathematicians: See here.
Programmers: Remember that division by 0 is undefined. Therefore, mod, which relies on division, is also undefined.
This represents division for positive X and D; it's made up of the integral part and fractional part:
(X / D) = integer + fraction
= floor(X / D) + (X % D) / D
Rearranging, you get:
(X % D) = D * (X / D) - D * floor(X / D)
Substituting 0 for D:
(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)
Since division by 0 is undefined:
(X % 0) = 0 * undefined - 0 * floor(undefined)
= undefined - undefined
= undefined
X % D is by definition a number 0 <= R < D, such that there exists Q so that
X = D*Q + R
So if D = 0, no such number can exists (because 0 <= R < 0)
I think because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this
REMAIN = Y ? X % Y : X
Another way that might be conceptually easy to understand the issue:
Ignoring for the moment the issue of argument sign, a % b could easily be re-written as a - ((a / b) * b). The expression a / b is undefined if b is zero, so in that case the overall expression must be too.
In the end, modulus is effectively a divisive operation, so if a / b is undefined, it's not unreasonable to expect a % b to be as well.
X % Y gives a result in the integer [ 0, Y ) range. X % 0 would have to give a result greater or equal to zero, and less than zero.
you can evade the "divivion by 0" case of (A%B) for its type float identity mod(a,b) for float(B)=b=0.0 , that is undefined, or defined differently between any 2 implementations, to avoid logic errors (hard crashes) in favor of arithmetic errors...
by computing mod([a*b],[b])==b*(a-floor(a))
INSTREAD OF
computing mod([a],[b])
where [a*b]==your x-axis, over time
[b] == the maximum of the seesaw curve (that will never be reached) == the first derivative of the seesaw function
https://www.shadertoy.com/view/MslfW8
I suppose because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this,
ans = Y ? X % Y : X
Also, in C++ docs its written that X % 0 or X / 0 ,results in an undefined value.
How computers divide:
Start with the dividend and subtract the divisor until the result is less then the divisor. The number of times you subtracted is the result and what you have left is the remainder. For example, to divide 10 and 3:
10 - 3 = 7
7 - 3 = 4
4 - 3 = 1
So
10 / 3 = 3
10 % 3 = 1
To divide 1 and 0:
1 / 0
1 - 0 = 1
1 - 0 = 1
1 - 0 = 1
...
So
1 / 0 = Infinity (technically even infinity is too small, but it's easy to classify it as that)
1 % 0 = NaN
If there is nothing to stop it, the CPU will continue to execute this until it overloads and returns a totally random result. So there is an instruction at the CPU level that if the divisor is 0, return NaN or Infinity (depending on your platform).
This will never end so the remainder is undefined (which is NaN for computers).
Why is X % 0 an invalid expression?
I always thought X % 0 should equal X. Since you can't divide by zero, shouldn't the answer naturally be the remainder, X (everything left over)?
The C++ Standard(2003) says in §5.6/4,
[...] If the second operand of / or % is zero the behavior is undefined; [...]
That is, following expressions invoke undefined-behavior(UB):
X / 0; //UB
X % 0; //UB
Note also that -5 % 2 is NOT equal to -(5 % 2) (as Petar seems to suggest in his comment to his answer). It's implementation-defined. The spec says (§5.6/4),
[...] If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
This answer is not for the mathematician. This answer attempts to give motivation (at the cost of mathematical precision).
Mathematicians: See here.
Programmers: Remember that division by 0 is undefined. Therefore, mod, which relies on division, is also undefined.
This represents division for positive X and D; it's made up of the integral part and fractional part:
(X / D) = integer + fraction
= floor(X / D) + (X % D) / D
Rearranging, you get:
(X % D) = D * (X / D) - D * floor(X / D)
Substituting 0 for D:
(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)
Since division by 0 is undefined:
(X % 0) = 0 * undefined - 0 * floor(undefined)
= undefined - undefined
= undefined
X % D is by definition a number 0 <= R < D, such that there exists Q so that
X = D*Q + R
So if D = 0, no such number can exists (because 0 <= R < 0)
I think because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this
REMAIN = Y ? X % Y : X
Another way that might be conceptually easy to understand the issue:
Ignoring for the moment the issue of argument sign, a % b could easily be re-written as a - ((a / b) * b). The expression a / b is undefined if b is zero, so in that case the overall expression must be too.
In the end, modulus is effectively a divisive operation, so if a / b is undefined, it's not unreasonable to expect a % b to be as well.
X % Y gives a result in the integer [ 0, Y ) range. X % 0 would have to give a result greater or equal to zero, and less than zero.
you can evade the "divivion by 0" case of (A%B) for its type float identity mod(a,b) for float(B)=b=0.0 , that is undefined, or defined differently between any 2 implementations, to avoid logic errors (hard crashes) in favor of arithmetic errors...
by computing mod([a*b],[b])==b*(a-floor(a))
INSTREAD OF
computing mod([a],[b])
where [a*b]==your x-axis, over time
[b] == the maximum of the seesaw curve (that will never be reached) == the first derivative of the seesaw function
https://www.shadertoy.com/view/MslfW8
I suppose because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this,
ans = Y ? X % Y : X
Also, in C++ docs its written that X % 0 or X / 0 ,results in an undefined value.
How computers divide:
Start with the dividend and subtract the divisor until the result is less then the divisor. The number of times you subtracted is the result and what you have left is the remainder. For example, to divide 10 and 3:
10 - 3 = 7
7 - 3 = 4
4 - 3 = 1
So
10 / 3 = 3
10 % 3 = 1
To divide 1 and 0:
1 / 0
1 - 0 = 1
1 - 0 = 1
1 - 0 = 1
...
So
1 / 0 = Infinity (technically even infinity is too small, but it's easy to classify it as that)
1 % 0 = NaN
If there is nothing to stop it, the CPU will continue to execute this until it overloads and returns a totally random result. So there is an instruction at the CPU level that if the divisor is 0, return NaN or Infinity (depending on your platform).
This will never end so the remainder is undefined (which is NaN for computers).
Can someone please explain the under-the-hood mechanics of x % y !=0 in C++? It evaluates to 0 if there is no remainder in integer division and it evaluates to 1 if there is any remainder of any amount. I find this to be quite useful, but I'd like to understand what is taking place, as the syntax is not intuitive to me.
I discovered this in a separate thread, which I do not have permissions to comment in:
Fast ceiling of an integer division in C / C++
Thank you.
(Please forgive any formatting faux pas; this is my first go here)
% is the integer remainder operator.
For example:
21 % 7 == 0
22 % 7 == 1
25 % 7 == 4
27 % 7 == 6
28 % 7 == 0
x % y != 0 is true if the integer division yields a non-zero remainder, false if it doesn't. x % y is simply that remainder; x % y != 0 tests whether that remainder is non-zero.
(Note that x % y != 0 can also be written as (x % y) != 0.)
It's slightly complicated when you consider negative operands.
The result of the expression is a Boolean (via the "not-equal-to" binary operator). So if the result of the modulus is non-zero, the full expression result is 1 (true). If the result of the modulus is zero, the full expression result is 0 (false)
Well it seems your problem is the modulo operater (%). So what this operator does is give you the remainder after we divide two numbers.
EX. 5 % 2 = 1 Because when we take 5/2 in integer division we get 2 however we clearly have 1 as a remainder. Another example is 22 % 4 = 2 Because 22/4 = 5 with 2 remainder.
Now that we understand this we can clearly see that if we get a non zero number the expression x % y != 0 will return true so we have two integers that dont divide each other. If we get this as false then we get two numbers that do divide each other. So you actually have it backwards because if the integer division is successful with no remainder x % y == 0 so 0 != 0 will be false.
Why is X % 0 an invalid expression?
I always thought X % 0 should equal X. Since you can't divide by zero, shouldn't the answer naturally be the remainder, X (everything left over)?
The C++ Standard(2003) says in §5.6/4,
[...] If the second operand of / or % is zero the behavior is undefined; [...]
That is, following expressions invoke undefined-behavior(UB):
X / 0; //UB
X % 0; //UB
Note also that -5 % 2 is NOT equal to -(5 % 2) (as Petar seems to suggest in his comment to his answer). It's implementation-defined. The spec says (§5.6/4),
[...] If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
This answer is not for the mathematician. This answer attempts to give motivation (at the cost of mathematical precision).
Mathematicians: See here.
Programmers: Remember that division by 0 is undefined. Therefore, mod, which relies on division, is also undefined.
This represents division for positive X and D; it's made up of the integral part and fractional part:
(X / D) = integer + fraction
= floor(X / D) + (X % D) / D
Rearranging, you get:
(X % D) = D * (X / D) - D * floor(X / D)
Substituting 0 for D:
(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)
Since division by 0 is undefined:
(X % 0) = 0 * undefined - 0 * floor(undefined)
= undefined - undefined
= undefined
X % D is by definition a number 0 <= R < D, such that there exists Q so that
X = D*Q + R
So if D = 0, no such number can exists (because 0 <= R < 0)
I think because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this
REMAIN = Y ? X % Y : X
Another way that might be conceptually easy to understand the issue:
Ignoring for the moment the issue of argument sign, a % b could easily be re-written as a - ((a / b) * b). The expression a / b is undefined if b is zero, so in that case the overall expression must be too.
In the end, modulus is effectively a divisive operation, so if a / b is undefined, it's not unreasonable to expect a % b to be as well.
X % Y gives a result in the integer [ 0, Y ) range. X % 0 would have to give a result greater or equal to zero, and less than zero.
you can evade the "divivion by 0" case of (A%B) for its type float identity mod(a,b) for float(B)=b=0.0 , that is undefined, or defined differently between any 2 implementations, to avoid logic errors (hard crashes) in favor of arithmetic errors...
by computing mod([a*b],[b])==b*(a-floor(a))
INSTREAD OF
computing mod([a],[b])
where [a*b]==your x-axis, over time
[b] == the maximum of the seesaw curve (that will never be reached) == the first derivative of the seesaw function
https://www.shadertoy.com/view/MslfW8
I suppose because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this,
ans = Y ? X % Y : X
Also, in C++ docs its written that X % 0 or X / 0 ,results in an undefined value.
How computers divide:
Start with the dividend and subtract the divisor until the result is less then the divisor. The number of times you subtracted is the result and what you have left is the remainder. For example, to divide 10 and 3:
10 - 3 = 7
7 - 3 = 4
4 - 3 = 1
So
10 / 3 = 3
10 % 3 = 1
To divide 1 and 0:
1 / 0
1 - 0 = 1
1 - 0 = 1
1 - 0 = 1
...
So
1 / 0 = Infinity (technically even infinity is too small, but it's easy to classify it as that)
1 % 0 = NaN
If there is nothing to stop it, the CPU will continue to execute this until it overloads and returns a totally random result. So there is an instruction at the CPU level that if the divisor is 0, return NaN or Infinity (depending on your platform).
This will never end so the remainder is undefined (which is NaN for computers).