Why i cant check if a variable have a value using == true? - c++

if(10) it is true, but if(10 == true) is false. Can someone tell me why the first case convert the number to bool but the second case didnt?

if (10) is equivalent to if (10 != 0), whereas if (10 == true) is if (10 == 1) (since true is promoted to the value 1 of type int).
In layman's terms: Two things that both happen to satisfy some property aren't automatically the same thing.
(E.g. doughnuts and frisbees are both round, but that doesn't mean a doughnut is equal to a frisbee. Integers and booleans can both be evaluated in a boolean context, but that doesn't mean that every integer that evaluates as true is equal to every true boolean.)

if( ... )
{
// if statement
}
To execute if statement in C++, ... should have a true value.
When you wrote if( 10 ){//something useful}
I think 10 treats as int but not bool variable. The following logic should be applied then
if( 10 ) -> if( bool( 10 ) ) -> if( true )
When you write if( 10 == true ){//something useful}, according to C++ standard, there should be the following logic behind the scene
if( 10 == true ) -> if( 10 == int( true ) ) -> if( 10 == 1 ) -> if( false )
You may write something like
if( 10 != false )
or
if( !!10 == true )
also
if( ( bool ) 10 == true ) // alternatively, if( bool ( 10 ) == true )
In old C (before C99), there is no false or true, but there are 0 or non-0 values.
In modern C (from C99), there is false or true (<stdbool.h>), but they are syntactic sugar for 0 and 1, respectively.
if( 10 ) // evaluates directly since 10 is non-zero value
if( 10 == true ) -> if( 10 == 1 ) -> if( 0 )

Because they are entirely different things.
In C, anything that is NOT false is automatically true, and C has a very strict definition of false.
You can think of if(10) as if(10 != false)
and likewise if (10 == true) as if((10 == true) != false)

10 is clearly not true, in the sense that 10 is a number and true is a boolean.
When you're in an if statement, the compiler has to evaluate the condition until it reaches either a true or a false. If it does not reach a true or a false, it has to convert it to a true or a false. As a general rule, 0 evaluates to false, and everything else evaluates to true.
So if(-1) is true, as is if(234) and so on.
The expression 10 == true already evaluates to false, so no further conversion is needed. if(10) is neither true or false, so the compiler has to convert it, using our rule above, and it becomes true.

Related

Why is my elif statement always executing in Godot?

I'm new to Godot programming, just to preface this. I'm trying to make it so that when you fall off of a platform without jumping you start accelerating downwards rather than just going down at a fixed speed. I almost have that, but my elif statement is happening every frame rather than the frame you leave the ground.
I've tried changing things, but I'm stuck at a logical dead end where any option I think of or find has resulted in the same or worse behavior.
extends KinematicBody2D
const UP_DIRECTION = Vector2.UP #up is up and down is down
# Declare member variables here.
var speed = 200 #speed of walk
var velocity = Vector2() #movement Vectors
var gravity = 1000 #gravity, it's real
var jump = 0 #jumping speed
var canjump = 0 #jumps left
var jumpcount = 1 #times you can jump
var nojump = false #did you fall or did you jump?
# Called every physics update.
func _physics_process(delta):
#jumping
if (canjump > 0 && Input.is_action_just_pressed("Jump") || is_on_floor() && canjump > 0 && Input.is_action_pressed("Jump")):
jump = -2000
canjump -= 1
nojump = false
#falling without jumping first
elif not (is_on_floor() && Input.is_action_just_pressed("Jump") && nojump == false):
jump = -gravity
canjump -= 1
nojump = false
#decelerating jumps
if (jump < 0):
jump += 45
#grounding jump variables
if(is_on_floor()):
canjump = jumpcount
nojump = true
#setting x and y
velocity.x = (Input.get_action_strength("Right") - Input.get_action_strength("Left")) * speed
velocity.y = gravity + jump
#using found inputs
velocity = move_and_slide(velocity, UP_DIRECTION)
pass
Here's my code, it tried commenting in the tdlr of what things are supposed to do. Again all I'm looking for is the reason why my elif statement is being applied every frame and how to fix that.
If you have a conditional that looks like this:
if condition:
prints("Something")
The execution flow would enter it when the condition is true.
Let us look at this as example:
if is_on_floor() && Input.is_action_just_pressed("Jump") && nojump == false:
prints("Something")
The above conditional requires three things:
is_on_floor() must be true.
Input.is_action_just_pressed("Jump") must be true.
nojump == false must be true. I mean, nojump must be false.
I think we can agree that does not happen all the time.
Now, if I negate the conditional:
if not condition:
prints("Something")
The execution flow would enter when the condition is false.
So, in a case like the one on your code:
if not (is_on_floor() && Input.is_action_just_pressed("Jump") && nojump == false):
prints("Something")
The conditional has one requirement:
not (is_on_floor() && Input.is_action_just_pressed("Jump") && nojump == false)`
Must be true. I mean:
is_on_floor() && Input.is_action_just_pressed("Jump") && nojump == false
Must be false. Double check D'Morgan's Law if you need to.
It is false when either:
is_on_floor() is false.
Or Input.is_action_just_pressed("Jump") is false.
Or nojump == false is false.
In other words, only one of these being false is sufficient.
To restate that. This condition:
not (is_on_floor() && Input.is_action_just_pressed("Jump") && nojump == false)`
Is equivalent to the following condition (by D'Morgan's law):
not is_on_floor() or not Input.is_action_just_pressed("Jump") or not nojump == false
By the way, using and and or is idiomatic in GDScript.
Wait, I can simplify that a bit:
not is_on_floor() or not Input.is_action_just_pressed("Jump") or nojump`
Thus, the execution flow will enter if either:
not is_on_floor() is true. I mean, if is_on_floor() is false.
not Input.is_action_just_pressed("Jump") is true. I mean, if Input.is_action_just_pressed("Jump") is false.
nojump is true.
And I reiterate that is either of them. Only one is sufficient. And I believe most of the time you haven't just pressed "Jump", also being on the air is enough. And I suspect nojump is false most of the time.
So, we can conclude that the execution flow will enter most of the time.
Write what you mean. You say in comments:
#falling without jumping first
Let us do that. What does falling mean? Does it mean on the air?
var falling := not is_on_floor()
Or do you also mean going down?
var falling := not is_on_floor() and velocity.dot(Vector2.DOWN) > 0.0
Alright, your pick. What does jumping first mean? Does it mean the player got in the air as a result of a jump? Ok... So you would do this when the player jumped:
jumped = true
Which I believe is this:
if canjump > 0 && Input.is_action_just_pressed("Jump"):
jumped = true
And reset it on the ground:
if is_on_floor():
jumped = false
Now we can say "falling without jumping first":
if falling and not jumped:
prints("something")
Almost as if it were the comment, but unlike the comment it can be executed.

how multiple OR's and AND evaluate

This is very simple question, but I can't get it. I have simple condition:
bool c = true || true || true && false;
Why this evaluation is true? As far as I know it evaluates like this:
true || true || true && false => true || true && false => true && false => false
But guess im wrong.
You just have to learn some few basic rules:
(a OR b) is true IF AND ONLY IF at least one of a or b is true.
(a AND b) is true IF AND ONLY IF both of a and b are true.
ORDER of Operators MATTERS: you can't just do the logic any way that you want. computer calculates the output of the a logical statement by an order. a simplified order is like this: First is Grouping (), Second is And, Third is OR.
so when you say bool c = true || true || true && false;. the computer says ok let's first calculate true && false. it is false! and then it calculates true || true || false which is true.
EDIT
Note 1: a complete list of logical operators and their precedence is heavily dependent on the language. you can refer to the documentation for that.
for C#
Note 2: the best practice is to use GROUPING like parenthesis because GROUPING is always of priority. for example it's better to say:
bool c = (true || true) || (true && false);
Think of OR || like addition and AND && as multiplication. There is a priority in there, in fact, you will sometimes see them written as such:
bool c = true + true + true + true * false
In this case, the first evaluation is true * false, then the rest of the ORs. In this particular case, the true order of evaluation of the ORs will depend on language/compiler.
If you want to force a particular order, you can always use parentheses.

What is the difference between this two condition?

What is the difference between this two conditions?. I tried to use both conditions but different output.
if(!(data1 == true || data2 == true))
{
// do something
}
And
if(data1 != true || data2 != true)
{
// do something
}
!(data1 == true || data2 == true) this condition is same as data1 != true && data2 != true
Using ! operator with == gives != and using ! operator with || will give &&.
Your 2nd condition data1 != true || data2 != true will be same as your 1 st condition If you replace || with && in 2nd condition
!(data1 == true || data2 == true)
This is equivalent of (see also De Morgan's laws):
(data1 != true && data2 != true)
Which is obviously different from
(data1 != true || data2 != true)
fist condition :
if(!(data1 == true || data2 == true))
{
// do something
}
It will false the evaluated result if the result is true and if the result is false then the result will be true.
If data1 == true is true it will not check data2 condition and make all condition false. so if data1 == true then whole condition is false. Same as data1. And if data1 or data2 is false (one is false) then the code will be executed.
Second Condition
if(data1 != true || data2 != true)
{
// do something
}
It will do the reverse of the first condition. First it will check that if data1 is not equal to true, so if data1 is false then the code will be executed.

C++ operators precedence

I am using this statement
if ((pm && pn) || (pm == false && pn == false))
it is supposed to return true only if both pm and pn are true or if both are false. But this is also returning true if only only first one (pm) is true.
So now it is acting like this:
0 0 = 1
0 1 = 0
1 0 = 1
1 1 = 1
but I need it to work like this:
0 0 = 1
0 1 = 0
1 0 = 0
1 1 = 1
can you tell me where am I making mistake?
What you want is simply:
if (pm == pn)
You are checking if pm is true twice. You also need to check if both are the same, not whether they are both true. So,
if ((pm == pn)
^^ ^^
pm && pm
should be
pm && pn
^
The whole expression can be simplified to
pm == pn
if the variables already have bool type.
Why not try xor?
if (!(pm ^ pn)) { /*...*/ }
Or simply equal?
if (pm == pn) { /*...*/ }
if ((pm && pm) || (pm == false && pn == false))
it is supposed to return true only if both pm and pn are true or if both are false. But this is also returning true if only only first one (pm) is true.
Because you made a typo. You meant pm && pn.
Instead just write if (pm == pn), which is equivalent along as the only semantic values are indeed true and false for both variables.
Plus, consider making your variable names clearer and more distinct.
Note that operator precedence has nothing to do with this.
Since the question's title asks about precedence, note that || has lower precedence than &&. So the two sets of inner parentheses are redundant, and the original expression is just a longer way of saying
if (pm && pm || pm == false && pn == false)
Now, fixing the obvious typo:
if (pm && pn || pm == false && pn == false)
Removing the unneeded explicit comparisons:
if (pm && pn || !pm && !pn)
And, finally, a less obvious transformation, which others have suggested:
if (pm == pn)

C++ Ternary operator logic

I'm having trouble figuring out what this if statement is doing. This is not my code so I am simply trying to understand what the Ternary operator is doing.
if((model[STRIDE].isLogging == true ? model[STRIDE].value : g_uiStride) == g_uiStride &&
(model[NUMVERTS].isLogging == true ? model[NUMVERTS].value : NumVertices) == NumVertices &&
(model[PRIMCOUNT].isLogging == true ? model[PRIMCOUNT].value : primCount) == primCount &&
(model[STARTINDEX].isLogging == true ? model[STARTINDEX].value : startIndex) == startIndex)
{
First,
(model[STRIDE].isLogging == true ? model[STRIDE].value : g_uiStride) == g_uiStride
could be written:
(model[STRIDE].isLogging ? model[STRIDE].value : g_uiStride) == g_uiStride
the ternary
model[STRIDE].isLogging ? model[STRIDE].value : g_uiStride
checks to see if model[STRIDE].isLogging is true. If it is, it takes the value model[STRIDE].value. If not, it takes the value g_uiStride. This is then compared to g_uiStride.
So, if it isn't logging, then this portion is automatically true because g_uiStride is compared to itself. If it is logging, it is true if mode[STRIDE].value == g_uiStride
and
#1.
if (model[STRIDE].isLogging is true then
RESULT1 = (model[STRIDE].value == g_uiStride) else
RESULT1 = (g_uiStride == g_uiStride)
)
#2.
if (model[NUMVERTS].isLogging is true then
RESULT2 = (model[NUMVERTS].value == NumVertices) else
RESULT2 = (mVertices == NumVertices)
)
#3.
if (model[PRIMCOUNT].isLogging is true then
RESULT3 = (model[PRIMCOUNT].value == primCount) else
RESULT3 = (primCount == primCount)
}
#4.
if (model[STARTINDEX].isLogging is true then
RESULT4 = (model[STARTINDEX].value == startIndex) else
RESULT4 = (startIndex == startIndex)
)
if (RESULT1 && RESULT2 && RESULT3 && RESULT4) {
/* yay */
} else {
/* damn */
}
In general the ternary conditional operator uses a condition to choose between two alternatives:
condition ? first_alternative : second_alternative
In this case it is very unnecessarily complicated by comparing to true and one object to itself
if((model[STRIDE].isLogging == true ? model[STRIDE].value : g_uiStride) == g_uiStride
This can be reduced to
if((model[STRIDE].isLogging ? model[STRIDE].value : g_uiStride) == g_uiStride
which is also equivalent to
if (model[STRIDE].value == g_uiStride || !model[STRIDE].isLogging
telling us that either value is equal to some global value, or we don't care because we are not logging anyway.
blah = (model[STRIDE].isLogging == true ? model[STRIDE].value : g_uiStride)
is the same as
if (model[STRIDE].isLogging) {
blah = model[STRIDE].value ;
} else {
blah = g_uiStride;
}
The ternary operator is as follows:
(condition) ? value_for_true_condition : value_for_false_condition
(model[STRIDE].isLogging == true ? model[STRIDE].value : g_uiStride) first checks to see if the isLogging == true, the (condition). If the condition is true the model[STRIDE].value value is used, if not true the g_uiStride value is used.
The statement as a whole checks the values on all those members of model, but only if the member .isLogging == true. Otherwise it uses the default value. Note that this statement will always be true if all members have .isLogging variable set to false.