Could abs(random()) % someNumberGreaterThanZero return zero? - sql

SELECT foo FROM bar
WHERE id >= (abs(random()) % (SELECT max(id) FROM bar))
LIMIT 1;
I saw this in another answer as an alternative to ORDER BY random(). I need to make sure id would always be greater than zero. Do I have to change >= to >?

Since x % y returns 0 when x is a multiple of y, the answer is "Yes, your expression could return 0".
So, if id must be greater than 0, you need to use > rather than >=. Of course, if the modulo operator didn't return 0, you could still use > instead of >= and you'd get the same effect.

Yes. If abs(random()) returned the value of max(id), then the modulo's result would be zero. Since abs(random()) can return any value between 0 & 9223372036854775807, this is definitely possible.

Yes it can return 0 in two ways
Consider that 3 % 3 == 0, 6 % 3 == 0, etc. Then you would get 0 if random() happens to be max(id) or an even divider thereof.
random() can also return 0 and 0 % anything == 0, that is the other possibility.

Yes, it should be > because modulo division can return 0( a mod a ==0, 0 mod a == 0). Also, you might want to check if (SELECT max(id) is not null/0 (a mod 0 is undefined in some systems, or a)

Related

SQL how to express "not equal to and not less than"

I am trying to use a comparison operator in SQL to say where not equal to or less than zero.
I have tried this but it comes up with an error
WHERE amount (<> 0 or < 0)
I have also tried:
WHERE amount !<= 0
but get syntax errors. Any help greatly appreciated
You can simply use:
WHERE amount > 0
With propositional logic, your condition is the same as a != 0:
a != 0 or a < 0
(a < 0 or a > 0) or a < 0
(a < 0) or (a > 0) or (a < 0)
two repeated conditions with or, you can just remove one
(a < 0) or (a > 0)
equivalent to a != 0
aka a <> 0
"not equal to and not less than" <=> "not (equal to or less than)" (see the De Morgan formulas here https://www.cuemath.com/data/de-morgans-law/), I have attached the screenshot of the relevant formula:
foo equal 0 to is represented as
foo = 0
foo less than 0 is represented as
foo < 0
foo equal to 0 or foo is less than 0 is represented as
foo = 0 OR foo < 0
this can be shortened to
foo <= 0
its negation is
NOT (foo <= 0)
alternatively, you can use
foo > 0
Note that NULL is a special case and you need to define what you intend NULL to yield. Since that was not specified, I'm focusing only on numeric inputs, but, at the end of the line, you will need to take into account NULL as a possible value as well if... Well, if it's possible in your scenario.

How to turn a number to zero if the result of a calculation is negative inside a squareroot in BigQuery?

I have a query that can result in a negative squareroot, leading to an error. I'm using BigQuery.
Is there a way to turn the result in to a 0 if inside de POWER() function is less than 0?
Here's my query:
UPDATE `table` SET
SW_FERTL = CASE
WHEN POR_CLEAN < 0.04 THEN 1
WHEN (1/((rho_matrix-RHOB)/(rho_matrix-rho_mud_filt)))*POWER(((RW/ILD)+(POWER((0.3*VSHALE/2), 2)-(0.3*VSHALE/2))), 0.5) > 1 THEN 1
ELSE (1/((rho_matrix-RHOB)/(rho_matrix-rho_mud_filt)))*POWER(((RW/ILD)+(POWER((0.3*VSHALE/2), 2)-(0.3*VSHALE/2))), 0.5)
END
WHERE DEPTH_M IS NOT NULL
The negative squareroot can happen here:
POWER(((RW/ILD)+(POWER((0.3*VSHALE/2), 2)-(0.3*VSHALE/2))), 0.5)
So, if the result of
((RW/ILD)+(POWER((0.3*VSHALE/2), 2)-(0.3*VSHALE/2)))
is less than zero, I would like to set it to zero instead.
Is it possible to do this?
Thanks in advance!
You can use GREATEST():
GREATEST(0, ((RW/ILD)+(POWER((0.3*VSHALE/2), 2)-(0.3*VSHALE/2))))
In many (if not most) practical cases you want to distinguish zeros coming from power(-4, .5) vs. power(0, .5)
So, you can consider below approach
SAFE.POWER(((RW/ILD)+(POWER((0.3*VSHALE/2), 2)-(0.3*VSHALE/2))), 0.5)
above returns NULL in case of negative argument

Obj-c wont parse if statement with mod

So Im using a simple if statement to increase an object's speed when an score is reached. Im using a very simple if statement that doesnt work. In this context, "pigSpeed" controls the velocity of the object.
float difference = (self.view.bounds.size.height/4) - flyingPig.center.x;
score += -(int)difference;
if (score % 1000 == 0 & score > 0)
{
pigSpeed++;
NSLog(#"pigfaster");
}
I know the score works properly, as it is displayed, as it appears, but the if statement just wont work and nothing happens. What am I doing wrong. I can add more code if needed.
& is the bitwise and operator; && is the logical and that you mean to use here. Your if statement should actually read:
if (score % 1000 == 0 && score > 0)
Further to what #victor ronin said...
float difference = ( self.view.bounds.size.height / 4.0f ) - flyingPig.center.x;
int newScore = score + difference ;
if ( newScore > 0 && ( newScore / 1000 > score / 1000 ) )
{
// did thousands place increment?
++pigSpeed;
}
score = newScore ;
I agree with andyvn22 - you should use && instead of &. However, there is one more problem.
Let's say you have score = 999
after you calculate difference and it's difference = -5
Your score will become 1004. 1004 % 1000 will be 4 (not a zero)
I think you should change your condition some way that even if you jump over 1000 you still increase a speed.
I had to give just a bit of leeway so 'if (score % 1000 == 2 && score > 999)'

100 <= x <= 150 as argument in if (), acting funny

I have an if statement followed by several else if statements. All of the if/else if statements have an argument structured something like this:
if (100 <= x <= 149) //do this
else if (150 <= x <= 199) //do that
else if ...etc...
However, for some reason only the first if statement ever gets executed. X can be 200 and only the first if statement will be recognized.
I'm not sure why it isn't moving on to the next else if statement when X doesn't fit the argument of the preceding statement. Does this not work in Obj-C? Any help is appreciated. Thanks
You need to rephrase the statements like:
if (x >= 100 && x <= 149) {
} else if (x >= 150 && x <= 199) {
} ...
Your first if is evaluated like:
if ((100 <= x) <= 149)
Let's have a look how that evaluates:
If x = 200, then (100 <= 200) is true and thus evaluates to the value 1 (which means true). And then 1 <= 149 is also true.
If x has a value smaller than 100, for example 10, then (100 <= 10) is false and thus evaluates to the value 0 (which means false). Again, 0 <= 149 is true.
So regardless of the value of x, the whole expression will always be true.
C is not math, so
if (100 <= x <= 149)
is NOT the same as
if (100 <= x && x <= 149)
Which is what you meant. The former will be true always, because 100 <= x <= 149 becomes
((100 <= x) <= 149)
leaving two possibilities: (1 <= 149) or (0 <= 149). Both are always true.
Chained comparisons like these don't work in C-based languages. Or rather, they do, but not how you'd expect.
100 <= x <= 149 gets evaluated as (100 <= x) <= 149. If x is over 100, then (100 <= x) will evaluate to true, or 1. If x is under 100, it's false, or 0. In either case, 0 <= 149 or 1 <= 149 is true, so the overall expression is true.
To fix this, change your conditions to look like this:
if (100 <= x && x <= 149)
That will make it work as you expect.
The compiler sees an expression formulated from binary operators. The <= symbol is a binary operator, as are =, >=, ||, &&, and so forth.
Just as with arithmetic, there is an order of precedence that the compiler must follow, evaluating the expression formed around each binary operator.
In arithmetic, you are probably familiar with this, as with these two examples:
2+5*7 This evaluates to 2+(5*7) or 37, because multiplication has precedence over addition.
2+3+21 is evaluated in the order the terms are read from left to right, since there is no other precedence rule. It becomes (2+3)+21.
So 100<=x<=150 is an expression of a similar type, where the binary operators are all the same, and thus have the same precedence. Once again, this is resolved by evaluating it from left to right, so it becomes (100<=x)<=150. If x>=100 the term in parentheses evaluates to TRUE, which has a numeric value of 1. Since 1 is less than 150, the rest evaluates to 1<=150, or TRUE, if x is greater than or equal to 100. On the other hand, it also evaluates to TRUE if x is less than 100, because the second comparison becomes 0<=150, which is TRUE.
The other recommendations to break this down with parentheses are correct if you aren't sure of the order of precedence for binary operators: (100<=x) && (x<=150). You can also write it as 100<=x && x<=150 since the order of precedence for value comparisons is higher than for logical operators.
Because if (100 <= x <= 149) is the same as if(1<=149) if you give 200 or another number to x. And that is correct always.
For example.
x=1
100<=1 is false so you get if(0<=149) which is true
x=200
100<=200 is true so you get if(1<=149) which is true
So you always get true for it.
So you must do it in another way, like this
if(x>=100 && x<=149) ...
Adding some additional parenthesis may help.
if ((100 <= x) && (x <= 149)) //do this
I don't think you can write math functions like this in objective-c... Try separating them and combining with an && statement:
if ( (100 <= x) && (x <= 149) ) { // "&&" = and, "||" = or, other math comparison operators are: <=, >=, <, >, ==, != (!= is does not equal))
//do this
} else if ( (150 <= x) && (x <= 199) ) {
//do that
} else if ...etc...
You've already got a lot of answers, but I'll add one more to cover one other possible point of confusion.
In C & Obj-C the boolean (and character) types are treated as integer types, which is not the case in call languages. So expressions like 'z' * true make perfect sense!
(Modern) C uses the type _Bool for boolean, which is defined to be large enough to hold 0 & 1. Cocoa uses the type BOOL for boolean, which is defined as signed char. CoreFoundation uses the type Boolean which is defined as unsigned char. All three define YES/true as 1 and NO/false as 0, while C itself treats any non-zero value as true.
The relation operators such as <, <= etc. are defined to return the int (yes, none of the booleans, not even _Bool) value 0 if the relation is false, and the int value 1 if the relation is true.
Given this and the left-to-right associativity of relational operators your:
if (100 <= x <= 149)
is parsed as:
if ((100 <= x) <= 149)
then 100 <= x evaluates to the int value 1 if x is greater than or equal to 100, otherwise it evaluates to the int value 0, so we get:
if (1 <= 149)
or
if (0 <= 149)
both of these evaluate to 1 so we get:
if (1)
and the if statement branches to the "then" branch if it's expression is non-zero.
It may be surprising, but the whole statement is evaluated without any use of booleans at all - it is all done with integers.
To achieve what you intended you need:
if((100 <= x) && (x <= 149))
etc. - which also doesn't use any booleans (&& is defined in terms of integers).

Weird Objective-C Mod Behavior for Negative Numbers

So I thought that negative numbers, when mod'ed should be put into positive space... I cant get this to happen in objective-c
I expect this:
-1 % 3 = 2
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
But get this
-1 % 3 = -1
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
Why is this and is there a workaround?
result = n % 3;
if( result < 0 ) result += 3;
Don't perform extra mod operations as suggested in the other answers. They are very expensive and unnecessary.
In C and Objective-C, the division and modulus operators perform truncation towards zero. a / b is floor(a / b) if a / b > 0, otherwise it is ceiling(a / b) if a / b < 0. It is always the case that a == (a / b) * b + (a % b), unless of course b is 0. As a consequence, positive % positive == positive, positive % negative == positive, negative % positive == negative, and negative % negative == negative (you can work out the logic for all 4 cases, although it's a little tricky).
If n has a limited range, then you can get the result you want simply by adding a known constant multiple of 3 that is greater that the absolute value of the minimum.
For example, if n is limited to -1000..2000, then you can use the expression:
result = (n+1002) % 3;
Make sure the maximum plus your constant will not overflow when summed.
We have a problem of language:
math-er-says: i take this number plus that number mod other-number
code-er-hears: I add two numbers and then devide the result by other-number
code-er-says: what about negative numbers?
math-er-says: WHAT? fields mod other-number don't have a concept of negative numbers?
code-er-says: field what? ...
the math person in this conversations is talking about doing math in a circular number line. If you subtract off the bottom you wrap around to the top.
the code person is talking about an operator that calculates remainder.
In this case you want the mathematician's mod operator and have the remainder function at your disposal. you can convert the remainder operator into the mathematician's mod operator by checking to see if you fell of the bottom each time you do subtraction.
If this will be the behavior, and you know that it will be, then for m % n = r, just use r = n + r. If you're unsure of what will happen here, use then r = r % n.
Edit: To sum up, use r = ( n + ( m % n ) ) % n
I would have expected a positive number, as well, but I found this, from ISO/IEC 14882:2003 : Programming languages -- C++, 5.6.4 (found in the Wikipedia article on the modulus operation):
The binary % operator yields the remainder from the division of the first expression by the second. .... If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined
JavaScript does this, too. I've been caught by it a couple times. Think of it as a reflection around zero rather than a continuation.
Why: because that is the way the mod operator is specified in the C-standard (Remember that Objective-C is an extension of C). It confuses most people I know (like me) because it is surprising and you have to remember it.
As to a workaround: I would use uncleo's.
UncleO's answer is probably more robust, but if you want to do it on a single line, and you're certain the negative value will not be more negative than a single iteration of the mod (for example if you're only ever subtracting at most the mod value at any time) you can simplify it to a single expression:
int result = (n + 3) % 3;
Since you're doing the mod anyway, adding 3 to the initial value has no effect unless n is negative (but not less than -3) in which case it causes result to be the expected positive modulus.
There are two choices for the remainder, and the sign depends on the language. ANSI C chooses the sign of the dividend. I would suspect this is why you see Objective-C doing so also. See the wikipedia entry as well.
Not only java script, almost all the languages shows the wrong answer'
what coneybeare said is correct, when we have mode'd we have to get remainder
Remainder is nothing but which remains after division and it should be a positive integer....
If you check the number line you can understand that
I also face the same issue in VB and and it made me to forcefully add extra check like
if the result is a negative we have to add the divisor to the result
Instead of a%b
Use: a-b*floor((float)a/(float)b)
You're expecting remainder and are using modulo. In math they are the same thing, in C they are different. GNU-C has Rem() and Mod(), objective-c only has mod() so you will have to use the code above to simulate rem function (which is the same as mod in the math world, but not in the programming world [for most languages at least])
Also note you could define an easy to use macro for this.
#define rem(a,b) ((int)(a-b*floor((float)a/(float)b)))
Then you could just use rem(-1,3) in your code and it should work fine.