I have the following problem
in my app i have severeal if-statements
if ( (number >= 1 && number <= 18) && !strcmp("half1-18", _myBetCh) ) {
}
Now I realized that I have to split this condition because I need a boolean variable after one condition
bool success = false,
if(!strcmp("half1-18", _myBetCh) {
success = true;
if (number >= 1 && number <= 18) {
}
}
Is there a workaround to this? Is it possible, for instance, to make an assignment withing the if-statement?
It's possible, like this:
if ((success = !strcmp("half1-18", _myBatCh)) && number > 1 && number < 18)
but I personally think assignments in conditions are messy and hard to read, and prefer this variation:
bool success = strcmp("half1-18", _myBetCh) == 0;
if (success && number >= 1 && number <= 18) {
// ...
}
Well, there is:
if ( !strcmp("half1-18", _myBatCh) && (success = true, number > 1 && number < 18) )
or, obviating the need for the success = false earlier
if ( (success = !strcmp("half1-18", _myBatCh)) && number > 1 && number < 18 )
Your way is easier to read though, so I would consider sticking with what you've got.
Related
Any idea why the else if statment will be never executed ? The value of difference is constantly changing when the program runs.
double difference = abs(reale_x[0] - reale_x[1]);
if (0 <= difference < 45) {
timer_counter += 1;
if (timer_counter == 30) {
cout << "CLICK" << '\n';
}
}
else if (difference > 50) {
timer_counter = 0;
}
That is not how comparation works in c++.
What this code
if (0 <= difference < 45) {
does is it first compares if 0 is smaller or equal to difference. It is then "replaced" by a bool value either true or false. And then a bool value (so either 1 or 0) is compared to 45. And it will always be smaller than 45. What you have there is an always true statement.
So the way you would write this if statement is
if (difference >= 0 && difference < 45){
Note that because of your else if statement it will not execute if the difference is >44 and <51
if (0 <= difference < 45) will be executed as if ((0 <= difference) < 45), which will be either 0<45 or 1<45 and will always be true. That's why the else part is not getting executed.
in mathematics, we see and write 0 <= x < 45 or something like that to define the range of the variable x. But in order to tell the computer the same thing, you have to tell more clearly. Saying, to have to tell the compiler, that the value of x is greater than or equal to zero and at the same time, that value will be less than 45, and you can tell the compiler by this statement: difference >= && difference < 45 . the && is an 'AND' operator in most of the languages.
I am using CLion IDE to code my C++ project. Sometimes it happens that the IDE tries to be more intelligent than me and gives me suggestions. I have a simple problem during code inspection (by CLion). It says the following code can be simplified, even though I believe it is the most simple form I can think of :
Code :
if (node.first >= 0 && node.first <= 45 &&
node.second >= 0 && node.second <= 30)
return true;
else
return false;
Assume node is of type std::pair<int, int>
The suggestion I get from the CLion IDE is the following:
Code Inspection comments :
Inspection info: This inspection finds the part of the code that can be simplified, e.g. constant conditions, identical if branches, pointless boolean expressions, etc.
Do you think this can be simplified more ?
CLion is hinting at you that this bit...
if (node.first >= 0 && node.first <= 45 &&
node.second >= 0 && node.second <= 30)
return true;
else
return false;
could just be re-written as
return node.first >= 0 && node.first <= 45 &&
node.second >= 0 && node.second <= 30;
Since an expression used as a condition in a control statement obviously has a natural conversion to true and false.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I'm writing a function that is passed a character as the first argument and an integer as the second. I need to validate both simultaneously. Specifically, the character must be between A and J (including A and J), and the integer must be between 1 and 10 (including 1 and 10).
The line I wrote is:
if (toupper(row) < 'A' || toupper(row) > 'J' || col < 1 || col > 10)
{
return 0;
}
else
{ ... rest of function ... }
but this is not working correctly. In my book I read that you could perform comparisons with characters because they really are just integers themselves, but I can't figure out why ths won't work. Could anyone point me in the right direction?
Edit to address some comments
0 is the number we're supposed to return if the input is not valid.
This line of code is part of a project that is being graded by a "test driver" that my teacher wrote. The test driver is reporting that my function is not returning the correct result when the input is invalid (character that is not between A or J, or a number that is lower than 1 or greater than 10).
I structured my code so that if the statement above is true, then it returns the code we were supposed to return, otherwise it proceeds with the rest of the function... So I can't figure out why his test driver is telling me that I'm not returning the code when given invalid input. The other problem is he doesn't let us see what the test driver is sending to our function, so I have no way of trouble shooting this.
I think that you shouldn't use toupper. Why?
Because maybe your professor use invalid input like:
a, 5
and you shouldn't allow lower cases to pass your test.
So in the end your if statement:
if ((row >= 'A' && row <= 'J') && (col > 0 && col < 11))
From your post it is not clear what does not work. You wrote if statement without any compound statement. So what is the criterion that something is wrong?!
For example you could write
if (toupper(row) < 'A' || toupper(row) > 'J' || col < 1 || col > 10) return false;
Take into account that negation of expression
if ((toupper(row) >= 'A' && toupper(row) <= 'J') && (col > 0 && col < 11) )
as it is written by #Ardel is equivalent to
if ( !( ( toupper(row) >= 'A' && toupper(row) <= 'J') && (col > 0 && col < 11 ) ) )
that in turn is equivalent to
if ( !( toupper(row) >= 'A' && toupper(row) <= 'J') || !(col > 0 && col < 11 ) ) )
that is equivalent to
if ( !( toupper(row) >= 'A' ) || !( toupper(row) <= 'J') || !(col > 0 ) || !( col < 11 ) )
that is equivalent to
if ( toupper(row) < 'A' || toupper(row) > 'J' || col <= 0 ) || col >= 11 )
that is at last equivalent to
if (toupper(row) < 'A' || toupper(row) > 'J' || col < 1 || col > 10) return false;
That is your original expression.
So there is no any sense in your post and in the answer of #Ardel.
So I do not understand for example why the answer of #Ardel was uo voted. Maybe it was up voted by whose who is unable to do such conversions as the negation of boolean expressions?:)
I can suppose (moreover after thinking about I am sure) that you should not apply function toupper to the character. For example
if ( row < 'A' || row > 'J' || col < 1 || col > 10) return 0;
The other problem is that you did not say what the function shall do if this condition will be passed successfuly. Maybe inside the function body you should reassign row the following way
row -= 'A';
that to use it as integer value between 1 and 10 inclusively.
I have a template class that takes an unsigned integer as template parameter, but I have to make sure that number is a prime. I can check it in the constructor, for instance, but it would be better to do it during compilation.
Here's the Assert template I'm using:
template <bool statement>
class Assert;
template <>
struct Assert<true> {};
I can simply create an object of this type in any piece of code which is going to be compiled, using my condition as parameter, and it won't compile if that condition is false. The problem is that I have to check if some number is prime. Let it be n.
I've came up with the idea of including a separate file "PrimeTest.h" and trying to divide n by each number from n-1 to 1 by including the same file from inside that file. That is how I use it:
#define SUSPECT n
#include "PrimeTest.h"
This is the "PrimeTest.h":
#ifdef SUSPECT
#ifndef CURRENT
#define CURRENT (SUSPECT-1)
#endif // CURRENT
#ifndef FINISHED
#if CURRENT>100
#define IS_PRIME
#define FINISHED
#else
#if SUSPECT%CURRENT==0
#define IS_NOT_PRIME
#define FINISHED
#else
#define CURRENT (CURRENT-1) // THAT DOES NOT WORK!!!
#include "PrimeTest.h"
#endif // SUSPECT % CURRENT != 0
#endif
#endif // FINISHED
#endif // SUSPECT
But here's the problem: I can't decrement CURRENT in any way I could come up with, including temporary values and #pragma push_macro directives.
Any ideas how to do that?
You do not need preprocessor to compute something at compile-time.
Usually, when computation is needed, you use template metaprogramming (or constexpr functions as suggested by chris in his answer)
Via template metaprogramming you can solve the task as follows:
First you define a template which can check at compile time if the given value N is divisble by D or any value lower than D greater than 1.
template <int N, int D>
struct tmp {
static const bool result = (N%D) && tmp<N,D-1>::result;
};
template <int N>
struct tmp<N,1> {
static const bool result = true;
};
The value tmp<N,D>::result is true only when the numbers 2, 3, ... D do not divide N.
With the above tool at hand, creating is_prime compile-time checker is fairly easy:
template <int N>
struct is_prime {
static const bool result = tmp<N,N-1>::result;
};
Now the compile-time value is_prime<N>::result is true when N is prime, and false otherwise. The value can be supplied to further templates, like the Assert of yours.
C++11 constexpr version that should be able to check numbers up to roughly 1500 on any compiler that implements the suggested recursion depth limit:
constexpr bool is_prime_helper( std::size_t target, std::size_t check ) {
return (check*check > target) ||
(
(target%(check+1) != 0)
&& (target%(check+5) != 0)
&& is_prime_helper( target, check+6 )
);
}
constexpr bool is_prime( std::size_t target ) {
return (target != 0) && (target !=1) &&
( ( target == 2 || target == 3 || target == 5 )
|| ((target%2 != 0) && (target%3 != 0) && (target%5)!=0 &&
is_prime_helper( target, 6 )));
}
to improve this, we do some fun with a binary search tree:
#include <cstddef>
constexpr bool any_factors( std::size_t target, std::size_t start, std::size_t step) {
return
!(start*start*36 > target)
&&
(
( (step==1)
&& (
(target%(start*6+1) == 0)
|| (target%(start*6+5) == 0)
)
)
||
( (step > 1)
&&
(
any_factors( target, start, step/2 )
|| any_factors( target, start+step/2, step-step/2 )
)
)
);
}
which we then use like this:
constexpr bool is_prime( std::size_t target ) {
// handle 2, 3 and 5 explicitly:
return
(target == 2 || target == 3 || target == 5)
||
(
target != 0
&& target != 1
&& target%2 != 0
&& target%3 != 0
&& target%5 != 0
&& !any_factors( target, 1, target/6 + 1 ) // can make that upper bound a bit tighter, but I don't care
);
}
#include <iostream>
int main() {
std::cout << "97:" << is_prime(97) << "\n";
std::cout << "91:" << is_prime(91) << "\n";
}
which will recurse ~ log_2(target/6) times, which means that the recursion limit of constexpr expressions of 512 that C++11 standard requests that compilers implement as a minimum is no longer a problem.
Live example, with debugging embedded.
This will work up to basically the limits of std::size_t on your system. I've tested it with 111111113.
This is insanely easier in c++14, as we no longer need one-line constexpr functions, but instead sane structure. See here.
constexpr bool any_factors( std::size_t target, std::size_t start, std::size_t step ) {
if (start*start*36 > target)
{
return false;
}
if (step==1)
{
bool one_mod_6 = target%(start*6+1) == 0;
bool five_mod_6 = target%(start*6+5) == 0;
return one_mod_6 || five_mod_6;
}
bool first_half = any_factors(target, start, step/2);
bool second_half = any_factors(target, start+ step/2, (step+1)/2);
return first_half || second_half;
}
Here's an amateur solution that is for positive numbers and done at compile time, but it can't go too far before it breaks due to a recursion limit. I suppose you could add a square root parameter that you calculate manually to allow it to go up to what it does now squared. It does take advantage of C++11's constexpr functions, though, to make the syntax a bit nicer to use without extra work. In any case, it might be a good start and I look forward to seeing answers that work better.
constexpr bool IsPrime(std::size_t N, std::size_t I = 2) {
return (N != 2 ? N%I : true) //make 2 prime and check divisibility if not 2
&& (N >= 2) //0 and 1 are not prime
&& (I >= N-1 ? true : IsPrime(N, I+1)); //stop when I is too big
}
You can even make that square root done for you. For this example, I'll make IsPrime into a helper so that IsPrime can only be called with N:
//basically does ceil(sqrt(N))
constexpr std::size_t Sqrt(std::size_t N, std::size_t I = 2) {
return I*I >= N ? I : Sqrt(N, I+1);
}
//our old IsPrime function with no default arguments; works with sqrt now
constexpr bool IsPrimeHelper(std::size_t N, std::size_t sqrt, std::size_t I) {
return (N != 2 ? N%I : true)
&& (N >= 2)
&& (I >= sqrt ? true : IsPrimeHelper(N, sqrt, I+1));
}
//our new prime function: this is the interface for the user
constexpr bool IsPrime(std::size_t N) {
return IsPrimeHelper(N, Sqrt(N), 2);
}
For me, this new version works with the number 521 where the other failed. It even works with 9973. The new expected high should be about the square of the old. If you want to go further, you could even modify IsPrimeHelper to increment by 1 when I is 2 and by 2 when I is not 2. That would lead to a new high of about twice this one.
For something portable to traditional C compilers:
// preprocessor-compatible macro telling if x is a prime at most 15-bit
#define PRIME15(x) (((x)>1)&(((x)<6)*42+545925250)>>((x)%30&31)&&((x)<49\
||(x)%7&&(x)%11&&(x)%13&&(x)%17&&(x)%19&&(x)%23&&(x)%29&&(x)%31&&(x)%37\
&&(x)%41&&(x)%43&&(x)%47&&((x)<2809||(x)%53&&(x)%59&&(x)%61&&(x)%67\
&&(x)%71&&(x)%73&&(x)%79&&(x)%83&&(x)%89&&(x)%97&&(x)%101&&(x)%103\
&&(x)%107&&(x)%109&&(x)%113&&(x)%127&&(x)%131&&(x)%137&&(x)%139&&(x)%149\
&&(x)%151&&(x)%157&&(x)%163&&(x)%167&&(x)%173&&(x)%179&&(x)<32761)))
(x)>1 because all primes are at least 2
(x)<6 because because we special-case the primes 2 3 5
42 is also a bitmap of these special primes (1<<2)+(1<<3)+(1<<5)
545925250 is a bitmap for 1 7 11 13 17 19 23 29, for a swift test of divisibility by 2 3 5
>>((x)%30&31) accesses said bitmaps for said swift test¹
(x)<49 (resp. (x)<2809 and (x)<32761) because we want to tell 7=√49 (resp. 53=√2809 and 181=√32761) prime
(x)%7&..&&(x)%47 and (x)%53&&..&&(x)%179 because we test divisibility
179 because the square of the next prime exceeds 15 bits.
If the macro is used to generate code, it's pretty efficient.
Try it online!
¹ The &31 is a hack to workaround a warning for negative x. No, replacing the first & with &&1& won't cut it for a certain compiler for an embedded CPU which, at maximum warning level, reports errors in constant expressions with a negative shift including in subexpressions that a short-circuit boolean requires to not evaluate.
You can use this constexpr to check if small number n < 51529 are prime at compile time :
static constexpr auto is_prime_51529(const int n) {
// will not be repeated 7 times
return (n > 1) & ((n < 6) * 42 + 0x208A2882) >> n % 30 && (n < 49 || n % 7 && n % 11 && n % 13 && n % 17 && n % 19 && n % 23 && n % 29 && n % 31 && n % 37 && n % 41 && n % 43 && n % 47 && (n < 2809 || 53 && n % 59 && n % 61 && n % 67 && n % 71 && n % 73 && n % 79 && n % 83 && n % 89 && n % 97 && n % 101 && n % 103 && n % 107 && n % 109 && n % 113 && n % 127 && n % 131 && n % 137 && n % 139 && n % 149 && n % 151 && n % 157 && n % 163 && n % 167 && n % 173 && n % 179 && n % 181 && n % 191 && n % 193 && n % 197 && n % 199 && n % 211 && n % 223));
}
I have an if statement that looks as follows:
int count=0;
string Check;
if ((count==4 && Check!="-s")||(count==4 && Check!="-S"))
If count equals 4 and Check equals "-s" or "-S" it still enters this if statement because of the count == 4. It totally seems to ignore the second part. Is there something I'm doing wrong?
It's always going to be the case that either Check!="-s" or Check!="-S". Hence, your if statement is equivalent to if (count==4).
Well, if Check is "-S", then it will not even check the second pair of conditions, because you check with ||. The same holds true for the opposite case. If one is false, the other is true. Replace that with a &&.
int count = 4;
string Check = "-S";
if( (count == 4 && // count is 4, alright.
Check != "-s") || // Check is "-S", alright I'm done thanks to || (OR)
(count == 4 &&
Check != "-S") )
{
// ...
}
int count = 4;
string Check = "-s";
if( (count == 4 && // count is 4, alright.
Check != "-s") || // Check is "-S", time to check the other condition pair...
(count == 4 && // count is 4, alright.
Check != "-S") ) // Check is "-s", which is different from "-S", perfect.
{
// ...
}
Now the corrected version:
int count = 4;
string Check = "-S";
if( (count == 4 && // count is 4, alright.
Check != "-s") && // Check is "-S", different from "-s", now on to the other condition!
(count == 4 && // count is 4, alright.
Check != "-S") ) // Check is "-S"... oh dang! No executed code for you.
{
// ...
}
If count == 4 and Check == "-s", then the expression to the right of the || is true. If count == 4 and Check == "-S", then the expression to the left of the || is true. So you have true or true which is true. Thus, your if-block is executed.
The right statement is:
if(count==4 && (Check != "-s" || Check!="-S"))
The statement that you wrote is true if you have count = 4 and Check = "-S" because then the first part of the OR is true.
Might be more clear to use:
if (count==4 && Check!="-s" && Check!="-S")
You should use !strcmp(Check, "-s") and !strcmp(Check, "-S") instead of !=.
If you use == you compare the pointers and that is no what you want. The pointers will always be different thus your second argument will always be true.
You want to enter the if body if and only if Check is != from either -s or -S and count is = 4 right?
if ( (Check!="-s" && Check!="-S") && count==4 )
should work.
or
if ( Check.tolower() !="-s" && count==4 )
should work.
(Do not remember the name of the function to lowercase a string, you have got to look it up)
Hope this help.