Can't Understand Code fragment - c

I cannot understand how the code is giving output of the prime factors of input..and what is the use of temp variable in this code?another question is what is the purpose of i=1 in the code fragment?
#include<stdio.h>
int main()
{
int number,i,temp;
scanf("%d",&number);
if(number<0)
{
printf("%d = -1 x ",number); //just printing
number=number*-1; //multiplication by -1
}
else
{
printf("%d = ",number); //just printing
}
for(i=2;i*i<=number;i++)
{
if(number%i==0)
{
printf("%d x ",i);
number=number/i;
temp=i;
i=1;
}
}
printf("%d\n",number);
return 0;
}
sample input:100
sample output:100 = 2 x 2 x 5 x 5
sample input:20
sample output:20 = 2 x 2 x 5

As previously mentioned, temp is unused.
The way this prints the prime numbers is by trying over and over to divide the number by the smallest number possible. That is the purpose of i=1.
So take 175.
First, the loop is initialized at 2. It then increments i until 175 % i == 0. When this happens, it means that i is a factor of 175. So it prints i and divides 175 by i. This ensures you won't double-count the factor. Here, this will happen first for i == 5. So now, num = 175/5 = 35.
At this point, i is reset to 1. The first thing that happens at the end of the loop block is that i is incremented to 2. So now again, it looks for the smallest factor. Again, it finds 5.
If i was not set to 1, the program would keep going up and it would miss the fact that 5 is a factor of 175 twice.
Eventually, when i > number, the program knows that it has found all the factors. This is because factors have to be less than the number they are factors of.
Hope this helps.

temp isn't used. i=1 resets the checking for factors at 1 once a factor is found

Here in this code..
i = 1
resets i as you want the prime factors.. else if it let to increment you will get values like 4 and 6 also.. which would be wrong.
no use of
temp = i;

Here temp variable is not used at all. You may remove it from pgm.
i=1 is done, so that checking of remainder if(number%i==0) can be started from value 2 again.

Related

Variable is exceeding specified limit in for loop

I have written code to find the units and tens digit of a number,but am facing a problem when the number is greater than 99.The value of i has been set to less than 10 inside the for loop but when i execute the code with no=100,I find that i has a value of 10.
Why is this happening?
#include <stdio.h>
int unit(int x){
return x%10;
}
int ten(int x){
int temp=x-unit(x);
if(temp==0){
return 0;
}
else{
for(int i=1;i<10;i++){
if(temp%(i*10)==0 && temp/(i*10)==1){
return i;
}
}
}
}
int main(){
int no=100;
printf("%d",ten((no)));
return 0;
}
Think about what happens when the number is greater than 99. You will not be able to find a value of i b/w 1 and 9 such that the expression in the if is true. You will need a value of i > 10, but of course, then it wouldn't be the tens digit of the number.
Your method only works for a specific case, ie, when the number is b/w 1 and 10^2. Sure, you could write some more code to make it work for numbers b/w 1 and 10^3, but that would just be a pain in the ass. Even then, you'd have to write more code if the number is greater than that.
Try to think of a solution for the general case. To do that, two facts would be very useful:
Dividing using / only gives the integer part of the answer. Eg: 66/10 = 6
% This operator gives you the remainder. Eg: 59%10 = 9
1) In the else block of ten() you are returning a value only if some condition is met. If the condition does not satisfy you are not returning anything. In that case a garbage value may be printed.
2) To get the tenth digit, that is a lot of work. Just change the function body to -
int ten(int x) {
return (x % 100) /10;
}
The numbers upto 99 gets correct result because the condition satisfies. Lets take 99 as an example. After unit digit subtraction you got 90. When i becomes 9, the temp%(i*10) becomes 0 and temp/(i*10) becomes 1.
When number is 100, after unit digit subtraction the number remains same(i.e. 100). But for values of i from 1 to 9 temp/(i*10) never becomes 1 and the loop quits, resulting in the absurd behavior. You will get the same behavior for all the numbers that are greater than 99 using your code.

Misunderstanding in basic for loop (C)

I have been going through some exercises from a recommended book I found on this website. I came across this following basic piece of code, which I could not fully understand.
#include <stdio.h>
int main(void)
{
int i;
for (i = 10; i >= 1; i /= 2)
printf("%d ", i++);
return 0;
}
This is my reasoning behind this program fragment:
Variable i is initialised to 10.
i is tested to see if greater or equal to 1, (which is always the case).
The third expression reads: i = i / 2, thus i is divided by 2 and its value stored in i.
In the printf statement i is incremented after each printf statement.
I simply cannot understand why the output of this program is:
1 1 1 1 1 1 1 1 ...
I get that the condition statement is always true, however shouldn't the first values be:
5 3 2 1 1 1 1 1?
Basically I cannot seem to understand why the value of i is straight away being stored as 1. Any corrections regarding my reasoning and/or insight on the matter will be appreciated. Please do excuse the basic nature of this question.
As #abelenky pointed out, the correct output is 10 5 3 2 1 1 1 .... The only mistake you made in your reasoning is that the statement i /= 2 gets evaluated after the body of the for loop, before testing the condition again. Another way to write the same loop would therefore be
for(i = 10; i >= 1; i = (i + 1) / 2)
printf ("%d ", i);
If you are running on Windows, try paging the output through more: myprog | more. This should allow you to see the beginning of the output of this infinite loop. On a linux machine, you could acheive the same result using more or less: myprog | less. Thanks to #EugeneSh for making the suggestion that this could be the issue.
Another way that I have found to view the initial output for programs like this is to hit Ctrl+C immediately after starting the program with Enter. This is not a "standard" method and may require very quick reflexes to get any results for a quick loop like yours.
A final suggestion is to limit the output you produce from the program directly:
int i, count;
for(i = 10, count = 0; i >= 1 && count < 100; i /= 2, count++)
printf("%d ", i++);
This will add a counter that will stop your output after 100 numbers have been printed and allow you to see the first numbers.
On the second line, you have 'i++'.
Thus at each iteration of the loop, it will also increment i by 1.
So supposing i = 1 when you start the loop. First it will be divided by 2 (i /= 2). Since i is an integer, it will become 0. Then, on the second line, you have 'i++', thus incrementing i.
So by the end of the loop iteration, i will be back to being equal to 1 (thus making this loop infinite).

C prime factorization (loop failure?)

I've been looking into this simple piece of code for 1.5 hrs now and do not find the mistake. I start going crazy ;)
Could anyone of you with a fresh mind and view give me a little hint, where I might have the mistake in? (I am relatively new to C)
The problem is: The code works fine for most of the numbers I entered and tested, but accidentically I found a number that does not work: 3486118 (or 55777888 which is a multiple of it) It goes right for the first loop(s), but after factor 2 it becomes an endless loop.
Here is my code: (any help is greatly appreciated)
// Program calculates prime factors of entered number and returns them
#include <stdio.h>
int main() {
long int num, num_cp;
long int product=1;
/*prime number array up to 100.000*/
long int prime[] = {2, 3, **[...cut out MANY numbers...]** 99971, 99989, 99991};
printf("Please enter a positive integer:\n");
scanf("%li", &num);//55777888 or 3486118 not working... why?
//copy the entered number to keep the original for comparison with "product" and "break;" if equal
num_cp=num;
printf("prime factorization of %li:\n\n", num);
for (int i=0; i<sizeof(prime); i++) {
if (num_cp%prime[i]==0) {
num_cp/=prime[i];
product*=prime[i];
if (product==num) {
printf("%li\n\n", prime[i]);
break;
}
printf("%li*", prime[i]);
//If prime factor found but "product" is still not equal to "num" reset loop counter "i" to -1 (==0 in next loop)
i=-1;
}
}
printf("END");
return 0;
}
"I've been looking into this simple piece of code for 1.5 hrs now and do not find the mistake. I start going crazy ;)"
Don't. Leave it. Go away and eat a pizza. Veg out in front of your favourite movie. Have a shower. Aim for a new high-score on 2048 (or whatever). Your brain gets stuck in a rut and you are no longer seeing your code. You are only seeing what you think your code is.
When you get your brain out of the rut, then -- and only then -- go back and actually read the code you wrote. Not the code you think you wrote, but the code you actually wrote. Yes, they are different.
The prime factors of 55777888 are 2·2·2·2·2·1743059, where the last factor is too large to be contained in your list.
You can fix this in your code: When the product is equal to the product of the prime factors you have found, num_cp is 1. If num_cp is greater than one after you have exhausted your prime list, it is a factor of num. If num/num_cp is smaller than the largest prime you have checked, you can assume that the remaining value of num_cp is a prime. If it wasn't you'd have found more factors earlier.
You can fix this by adding an additional check after your main loop:
if (num_cp > 1) printf("%li\n\n", num_cp);
(If long int is a 64-bit number on your system, you're still not safe: The remaining factor might be made up of several numbers that are not in your array.)
Finally: Resetting the for loop counter so that the loop starts over isn't a good idea. It always starts from the beginning and re-checks primes that you have already checked. And it just isn't natural program flow, which makes it hard to read. A while loop instead of the inner if block would be more natural in my opinion.
Edit: To illustrate:
#include <stdio.h>
int main() {
long int num;
/* prime number array up to 100.000 */
long int prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
int nprime = sizeof(prime) / sizeof(*prime);
num = 55;
printf("%li == ", num);
for (int i = 0; i < nprime; i++) {
long int p = prime[i];
if (num <= 1) break;
while (num % p == 0) {
num /= prime[i];
printf("%li", p);
if (num > 1) printf(" * ");
}
}
if (num > 1) printf("%li", num);
printf("\n");
return 0;
}
Things to note:
Instead of resetting the main loop counter i, a while loop is used, which consumes all repetitions of the same factor. If a prime p doesn't divide the number, the while loop isn't entered, just like an if clause.
I've removed the copy of num and used num throughout, mainly to remove clutter. I've also removed the product. Your logic that all prime factors should multiply to the original number, is good. But it also works the other way round: After dividing the number by all primes, we are left with 1. And we have to divide the number anyways. By removing the product, we have to keep track of only one variable instead of two.
I've moved the break condition to the front, so we catch negative numbers and 0 early.
That said, your way to code isn't wrong, just maybe a bit unusual in places.

figure out the prime numbers between 0 and 1000?

I'm trying to make a programm that can calculate the prime numbers between 0 and 1000, the compiler says it has no warning and no erros too, but when i run the programm it gives me an execution error, i have no ideia what it is, does anybody could take a look at my code??
NOTE: i'm a beginner in programming.
#include <stdio.h>
#include <stdlib.h>
int main(){
int i=0;
for (i=0;i<1000;i++){
if (i % 1 == 0 && i % i == 0){
printf("%d",i );
}
printf(" ");
}
return 0;
}
You are performing a division by zero in
i % i == 0
for i = 0.
Moreover, even if you start you cycle from i = 1, the code will give you every integer between 1 and 999, for the expression
i % 1 == 0 && i % i == 0
is true whenever i != 0. Here is a fixed algorithm (not the most efficient, admittedly):
#include <stdio.h>
int main(){
int i; /* no need to initialize to zero */
int j; /* we need a second counter */
for (i=2;i<1000;i++){ /* start from 2 -- one is not prime */
for (j=2;j<i;j++){ /* check for nontrivial divisors */
if (i % j == 0) {
break; /* nontrivial divisor found -> not a prime */
}
}
if (j == i) { /* this means the cycle above run till end */
printf("%d ",i ); /* hence no nontrivial divisors, hence a prime */
}
}
printf("\n");
return 0;
}
The problem is with the expression i % i. In the first iteration of your loop, i is 0, so you are dividing by zero.
You should iterate from 1 to 1000, because dividing with 0 is not allowed and it gives floating point exception.
Also, your algorithm is not correct.
Use code from here:
http://www.programmingsimplified.com/c/source-code/c-program-for-prime-number
What happens when i is 0? My guess is you want to start your loop at 1 (as well as fix your prime number check).
Below python code may help you for following purposes:
To figure out the total number of primes in the range of 0 to given number (upper limit)
To know about each and every number whether that is prime or not
The Complete list of primes fall in the specified range
primes=[]
limit = int(input('What is the maximum limit?'))
for n in range(2,limit+1):
for x in range(2,n):
if n%x == 0:
print('{} -> Not prime'.format(n))
break
else:
primes.append(n)
print('{} -> Prime'.format(n))
print(primes)
print('Total {} primes found'.format(len(primes)))
If you don't want non-prime numbers to display then you can comment out #print('{} -> Not prime'.format(n)) this line and if you don't even want to know all primes comment the consecutive print statement as well i.e. #print('{} -> Prime'.format(n))

Displaying primes from 2-10,000 in C

I'm struggling with this (optional) problem my professor recommended I try. Basically, my task is to write a program which displays all prime integers from 2-10,000 using my own user-defined function to determine prime-ness. It sounded simple enough but I'm having major difficulties debugging my program. For some reason, my code only displays 2 and 3 before ending.
#include<stdio.h>
//function declaration
int prime(int);
//main body
int main(void)
{
int x=2, y;
for (x=2;x<=30;x++)
{
y=prime(x);
if (y!=0)
printf("%d\n", x);
}
getchar();
return(0);
}
//function definition
int prime(int x)
{
int y;
for (y=2; y<=(int)sqrt(x); ++y)
{
if (x%y==0)
return 0;
}
if (y==(int)sqrt(x))
return 1;
}
Instead of returning 1 if x is prime, my prime checking function seems to return a random large number (2686xxx) but that shouldn't be an issue because all primes return 0. If I run something like:
if (y==0)
printf("%d\n", x);
I see a list of all non prime numbers. If I run something like:
printf("%d %d\n", x, y);
I see a list of all integers from 2-10,000 and the result of my prime checking function (0 for non-primes, 2686xxx for primes).
Why doesn't the opposite (y!=0) display a list of prime numbers? What is causing my code to stop after just displaying 2 and 3? Why is my prime function returning a weird integer instead of 1? Finally, I'm still a beginner but how can I write better code in general? I don't think I'm breaking any of the standard accepted practices but how can I make my code more clean or efficient?
Thanks in advance for the help!
Your loop continues if y==(int)sqrt(x). So when it finishes, they're not equal. What you wanted is:
if (y>=(int)sqrt(x))
return 1;
But this is not needed at all. Just return 1; is sufficient. You've already returned zero if the number isn't prime.
If you wanted only a single return statement:
int prime(int x)
{
bool isPrime = true;
int y;
for (y=2; y<=(int)sqrt(x); ++y)
{
if (x%y==0)
{
isPrime = false;
break;
}
}
return isPrime;
}
Don't use the sqrt() function. In mathematics if you have 'x = sqrt(y)'. If you square both sides you will get something like this 'x * x = y'. This expression in c is tremendously faster than the sqrt function. Thus instead of doing:
y <= (int)sqrt(x)
Have you for loop guard be something like this:
y * y <= x
Here is a running example of your problem:
Primes 2 -> 10000
At the end of your prime function just return 1. If it wasn't prime it would have returned 0 earlier. Right?
As it is you've made a function which sometimes returns nothing at all. Which means that it returns whatever random value happens to be in the register.
You can use sieve of eratosthenes or sieve of atkin to mark all the prime numbers in an array and then display the prime numbers. It will be time efficient although it incurs some space complexity.
e.g if you want to display prime numbers from 1 to 10
Leave of 1. Its not a prime. Its neither prime nor composite.
So start from 2.
consider this array of size 10 = 2 3 4 5 6 7 8 9 10
Traverse from 2. If an element is not highlighted highlight all its multiples.
i.e for 2 highlight its multiples 4 6 8 10
==> 2 3 4 5 6 7 8 9 10
For 3 do the same
==> 2 3 4 5 6 7 8
9
10
Then do it for the rest of the no.s i.e. 5 and 10 (Here 7 dont have multiple)
Finally print the non highlighted elements. 2,3,5,7.
Repeat this procedure for any other ranges.
Since you are interested in writing computer programs for prime numbers, perhaps you would like to turn this paper into a computer program. It deals with prime numbers and is similar to the sieve you were trying to create in C.
https://graviticpropulsion.files.wordpress.com/2015/04/prime-number-theory.pdf
I'm not sure if it is faster or less memory intensive, but I'm curious myself how high of a prime number it can find before it becomes too intensive for a computer.

Resources