I created a custom boolean function named "isPrime()", some how I made it work but I don't know why it works, any explanation in plain english will be appreciated.
for (i = 3; i < 100; i++)
{
if (isPrime(i))
{
std::cout << i << "\n";
}
}
// I don't understand why this loop works:
bool isPrime (int i)
{
int j;
for (j = 2; j < i; j++)
{
if (i % j == 0) // 3 / 2
{
return false;
}
}
return true;
}
As you can see the isPrime() function has a loop so once it's finished, it should return true anyway because the return true; is outside of the loop and compiler will read return true; once the loop is finished. How the isPrime() function can return false when the it is returning true at the end?
If a function reaches a return statement at any point, it will exit completely, no matter where the return statement is, and control will go to the function who called it (in this case, I am assuming main).
When i % j == 0
it will return false and the loop finish
then the last statement "return true" will not run
Check this code segment.
if (i % j == 0) // 3 / 2
{
return false;
}
Because of this code segment when the number is divisible by value of j without any remainders function will return FALSE.
Simply when your if condition is true function returns FALSE. If method never comes to the inside of if condition then it returns TRUE
The function will return only once in execution: and are exit to the called function when return is executed
Logic is that :
a prime number is A prime number can be divided, without a remainder, only by itself and by 1:
so when i % j == 0 is true means that j is a factor of i hence it is not a prime so return false and exit the function
Related
I am writing some function which basically takes in input a range and a 1D vector. It looks at each number in the range of values given of the vector such that:
1) If the number to the left of it is 0 they swap positions.
2) If the number to the left of it is equal to it they add.
Now up till now this was good. The issue arises when I am trying to add return statements:
1) It should return True after all iterations are complete and at least one of the if conditions is entered in each iteration.
2) It should return false after all iterations are complete and none of the conditions are entered.
Now if I put these return statements in the loops they would terminate this function here but this is not desirable since it needs to go through all the iterations first. Is the current code comparable with this or do I need to redo it in a different manner ( if not where could the return statements go?)
bool proc_num(std::vector<int>&v, int LB, int UB) {
bool check = false;
for( int i=LB+2 ; i<UB; i++) {
for(int j = i-1; j>LB; j--) {
if(v[j] == 0){
v[j] = v[i];
check = true;
} else if(v[j] == v[i]) {
v[j]= v[j]+v[i];
v[i] = 0;
check = true;
}
}
}
return check;
}
You can simply add a boolean to make sure that at least one of the if conditions are entered.
This question already has answers here:
C - determine if a number is prime
(12 answers)
Closed 4 years ago.
I'm currently learning c++ for the first time and I've written a cpp bool function to find if an integer is a prime number.
The code was:
bool isPrime(int n) {
for (int i = 2; i < n; i++) {
if (n % i == 0)
return false;
else
return true;
}
}
However, it turns out that 9 is also considered as a prime number with this function.
I found a solution just by removing the else statement,
bool isPrime(int n) {
for (int i = 2; i < n; i++) {
if (n % i == 0)
return false;
}
}
but I still don't get why the else statement had anything to do with it in the first place. Can anyone help me out?
Because of the if statement.
if (n % i == 0)
return false;
else
return true;
The condition reads "if n is divisible by the current number". The condition will either be true (in which case n is not prime) or false (it might be prime) so one of the branches must be taken and the function will exit in either case, possibly prematurely.
Removing the else prevents early return, however, it also prevents true being returned by the function. You can simply add return true to the end of the function:
bool isPrime(int n) {
for (int i = 2; i < n; i++) {
if (n % i == 0)
return false;
}
return true; // must be prime
}
The only way a number is prime is when the loop completes, so the return true; statement should be outside the loop. You only have to check numbers up to the square root of n.
Also, you need to handle the case where n is less than 2.
#include <cmath>
bool isPrime(int n)
{
if (n < 2)
{
return false;
}
for (int i = 2; i <= sqrt(n); i++)
{
if (n % i == 0)
{
return false;
}
}
return true;
}
Because it will return in the first loop!
When the function enters the else, it will return true.
Any odd number will return true — and 9 is the first odd number bigger than 1 which is not a prime.
Try this:
bool isPrime(int n) {
for (int i = 2; i < n; i++) {
if (n % i == 0)
return false;
else
continue;
}
return true;
}
9 is odd. Which means it's not divisible by 2. In fact it's the first odd number after 1 that is not prime. Your code explicitly returns true if n is not divisible by 2.
for (int i = 2; i < n; i++) {
if (n % i == 0)
return false;
else
return true;
}
The first time the for loop runs, i is 2. Either n % i == 0 is true or it is false. If true, your function immediately returns false. If false, your function immediately returns true.
You need to move the return true statement outside the loop. Only after checking all possible divisors by completing the for loop do you know if the number n is prime.
Sorry if the question seems really trivial but I'm just learning how to code and this one kept me in front of the computer for about 2 hours without getting to realize why this happens.
I'll pass the code below.
So, in order to keep it straightforward:
isPrime() is a function that just checks if a current number is Prime or not.
nPrime() is a function that returns the n-ism prime number, given N as the parameter.
The key point here is the main function and, more precisely, the number value in the first while-loop.
If you run this code, when it reaches the last prime number by which number is divisible, it'll enter an infinite loop. This can be easily solved if you just change the first while condition from while(number > 0) to while(number > 1).
That's the weird thing I can't come to realize:
If the inner second while-loop won't exit as long as number % nPrime(index) != 0 and the last instruction of the outter first while-loop is number /= nPrime(index);, how come the program enters an infinite loop?
That last instruction set number's value to 0, so the first while-loop condition should return false and exit the loop.
What am I missing?
Thank you all for your time and patience.
PS: I got downvoted and I don't know why, so I'll make an clarification:
I've done the research. As far as I know, every source seems to agree on the same point:
the > condition returns true if and only if left operand is greater than right operand.
Which takes me to the previously written question: if number is equal to 0, how's the while-loop not evaluating the number > 0 as false and exiting from the iteration?
#include <iostream>
using namespace std;
bool isPrime(int);
int nPrime(int);
int main() {
int number = 264;
if (number > 0)
{
int index = 1;
while(number > 0)
{
while (number % nPrime(index) != 0)
{
index++;
}
cout << nPrime(index) << endl;
number /= nPrime(index);
}
}
else
cout << "Error";
return 0;
}
bool isPrime(int n)
{
bool isPrime = false;
int totalDividends = 0;
for (int i = 1; i <= n; ++i)
{
if (n % i == 0)
totalDividends++;
}
if(totalDividends == 2)
isPrime = true;
return isPrime;
}
int nPrime(int n)
{
int result = 0;
for (int i = 0; i < n; ++i)
{
do
{
result++;
} while (!isPrime(result));
}
return result;
}
What am I missing?
That last instruction set number's value to 0
No it doesn't, it never gets that far. When number equals one then number % nPrime(index) != 0 is always true, so the inner while loop never exits.
Your understanding of while loops is perfect, it's your understanding of what your own code does that is in error. This is normal for bugs like this.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I just came upon one problem. I wanted to compare whether my Eratostenes's Sieve contains prime numbers or not. In the code i have this line
if (sieve[2] == is_prime(2)) // returns false
printf ("true");
Now, sieve[2] is a boolean and it's value is true (I even checked in the array, so there's no doubt about it). is_prime(2) is a boolean aswell (I also checked).
Now my problem. The line presented above returns false. Yes - it returns false even though it's statement is:
if ( true == true ) // which normally returns true
printf ("true");
However, after removing one equation sign:
if ( sieve[2] = is_prime(2) ) // returns true
printf ("true");
This statement returns true.
Can someone briefly explain how does one equation mark work in this case in comparison to ==?
Thanks in advance
EDIT
is_prime:
bool is_prime(int x) {
unsigned int i,j,k;
if (x < 2) return false;
else {
for (i=2; i!=x; i++) {
if (x == i) return true;
else if (x % i == 0) return false;
}
}
}
sieve:
const int n = 10000;
bool sieve[n+1];
.
.
unsigned long int i;
sieve[0] = sieve[1] = false;
for (i=2; i<=n; i++) sieve[i] = true;
for (i=2; i*i<=n; i++) {
if (sieve[i]) {
unsigned tmp = 2*i;
while (tmp <= n) {
sieve[tmp] = false;
tmp += i;
}
}
}
[EDIT2]
The problem was with "is_prime(x)" Changed loop condition from "i!=x" to "i<=x"
Sorry for the trouble and thanks for the answers
UPDATE
bool is_prime(int x) {
unsigned int i,j,k;
if (x < 2) return false;
else {
for (i=2; i!=x; i++) {
if (x == i) return true;
else if (x % i == 0) return false;
}
}
}
Your is_prime() (above) is broken, with undefined behaviour, as when x is 2 (or indeed any actually prime number) it reaches the end of the function without having a return statement - the i!=x test means the x == i inside the loop can never be true.
is_prime(2) it's likely to return effectively random results (based on left over stack or register content / in your documented output it's seeming "returning" x itself, presumably because your ABI uses the same CPU register or stack address to pass in the argument and pass back the function's return value).
Specifically for 2, flow enters the first else clause, then with i=2 the first i!=x test fails and the for loop immediately exits... there's no return after the for's scope. Minimally corrected code (faster implementations are possible, but keeping the simplicity and intended logic):
bool is_prime(int x)
{
if (x < 2) return false;
for (int i = 2; i < x; ++i)
if (x % i == 0)
return false;
return true;
}
Equivality / ==
With sieve[2] == is_prime(2) it's checking they have the same value - possibly after converting one of the values to enable the comparison, but you say they're both booleans so that's not necessary. This would yield a "true" value for the if when they're both true or both false.
Now my problem. The line presented above returns false. Yes - it returns false even though...
That doesn't make any sense... I suggest you add the following before the if statement to check the variables' values:
std::cout << "sieve[2] " << sieve[2] << " (bool)" << (bool)sieve[2]
<< ", is_prime(2) " << is_prime(2) << std::endl;
I even checked in the array, so there's no doubt about it
Be wary of mistakes like seeing the array content displayed ala { true false true false } and thinking [2] is the second value... it's actually the third. as array indexing starts at 0.
Assignment / =
With sieve[2] = is_prime(2) you're assigning the value of is_prime(2) into sieve[2], and the if statement is deemed "true" if that value is deemed true in a boolean context (i.e. it's a boolean with value true, or a non-0 number or pointer etc.). For most data types, the execution flow of if (sieve[2] = is_prime(2)) ... is the same as simply if (is_prime(2)) ..., but of course it also modifies sieve[2].
It assigns the right hand operand to left, and returns the left operand.Since you are assigning true to your variable, it evaluates to true. If you set your variable to false, you don't get the output, e.g:
bool x;
if(x = false)
printf("this won't be printed");
Here the equal affect the left operator with the value of the right operator then test the value. So the result must be the value of the right operator.
Your loop in is_prime will never run for the check x == i will be true, because it runs as long as x != i. Those two conditions are mutually exclusive.
That means the function will end without a return statement, which leads to undefined behavior.
This
if ( sieve[2] = is_prime(2) )
contains an assignment, not a comparison.
As the value of an assignment is the value assigned, it is true whenever is_prime(2) is.
However, let's look at your is_prime and see what happens if we pass it a 2...
bool is_prime(int x) {
unsigned int i,j,k;
So far, so good, but j and k are never used, so they shouldn't really be here.
if (x < 2) return false;
2 isn't less than 2, so we'll continue...
else {
for (i=2; i!=x; i++) {
OK, set i = 2, and compare it to x which is 2, and... oops, i is equal to x, so we'll abandon the loop immediately...
if (x == i) return true;
else if (x % i == 0) return false;
}
}
... and fall through here, where we're not returning a value like we promised, and causing undefined behaviour.
}
So, your program is undefined (you really should switch on compiler warnings, or start listening to them).
And this happens on every number that is prime.
You can rewrite the loop like this:
for (i=2; i <= x; i++) {
if (x == i) return true;
else if (x % i == 0) return false;
}
or
for (i=2; i < x; i++) {
if (x % i == 0) return false;
}
return true;
Why does if (is_prime(2)) appear to work?
(Since this code is undefined, the following is largely speculation and should only be taken with suitable measures of salt.)
Often, when a function is supposed to return something but doesn't, the calling function will just grab whatever is stored in the place where the return value should have been and use that.
This value is in this case very likely not the same as the bit pattern that represents true, so will compare unequal to true, in if (is_prime(2) == true).
It will however, also very likely, not be the bit pattern that represents false either, so will be considered true in a conditional, if(is_prime(2)).
I have the following code for checking whether the first 20 positive numbers are prime using a bool function.
#include <iostream>
#include <cmath>
using namespace std;
bool prime(int);
/*
function to evaluate whether a positive integer is prime (true)
or not prime (false)
*/
int main()
{
for(int x=1; x<=20; x++)
{
cout << x << " a prime ? (1 yes, 0 no) "
<< prime(x) << endl;
}
return 0;
}
bool prime(int x)
{
for(int i=2; i<= sqrt(x); i++)
{
if ((x%i) != 0)
return true;
else
return false;
}
}
It works for all numbers 1 to 20 apart from 2 and 3 where the output is 0 instead of 1. I think I know why. For x = 2 and 3 there is no i in the for loop such that i<=sqrt(2) or i<=sqrt(3).
How could I modify the code so it would work for these values too?
Also there is an error message "Control may reach end of non-void function". Why is this?
Thanks.
Modify your prime function to the following
bool prime(int x)
{
if (x < 2) return false;
for(int i=2; i<= sqrt(x); i++) {
if ((x%i) == 0) return false;
}
return true;
}
The Control may reach end of non-void function error message tells you that your prime function does not return in all cases (When you pass 1 to your function, it does not go in the for loop, and so exit without explicitly returning anything, which could lead to undefined-behavior). In general, you want to have a return instruction outside of any conditionnal structure.
You return in the wrong place in your prime function.
bool prime(int x) {
for(int i=2; i<= sqrt(x); i++) {
if ((x%i) == 0)
return false;
}
return true;
}
In your existing function you only test the very first i. The compiler warning refers to how if the loop finishes without returning (although this is easy for us to see it never will), then control will reach the end of prime without returning a value.
Extract return true result from cycle!
bool prime( int _x )
{
double x = sqrt( _x );
for( int i = 2; i <= x; ++i )
if ( !( _x % i ) )
return false;
return true;
}
you can also use this without need to sqrt function , there it is
bool prime (int num){
int i,temp;
for (i=2; i<=num/2) && temp; i++)
if (num%i==0)
temp = 0;
return temp;}