I am working on a functions HW for my programming class and Im trying to write a function that will allow me to do exponent math (in a simple form). (Oh and I can't use the actual exponent function, I have to write my own function using for loops, if statements or other things like that.)
EX: user enters base and then enters the power to raise it by. So the user enters:
5
3
it should be 5 to the 3rd power, so it should output 125 (5x5x5). However my for loop is not working properly. How should I structure my for loop to properly handle exponent math?
code:
int main(){
int base, pow;
scanf("%d", &base);
scanf("%d", &pow);
int i;
for (i=0; i<=pow; i++) {
i *= base;
printf("%d\n", i);
}
printf("%d", i);
Well you're using the same variable for the loop and the result. You don't want to do that.
int j = 1;
for(i = 0; i < pow; i++)
{
j*= base;
}
Is what you want. You're also off by one on the loop count. With i <= pow you have
i=0, j * 5 = 5, i=1
i=1, j * 5 = 25,i=2
i=2, j * 5 = 125,i=3. This is where you want to stop but 3 <= 3 so it goes again.
i=3, j *5 = 625,i=4. 4 is not <= 3 so it will then stop here.
The loop is obviously wrong:
for (i=0; i<=pow; i++) {
i *= base;
printf("%d\n", i);
}
You are multiplying the loop counter by base for some reason, which will not yield any good.
The right one would be:
int result = 1;
for (i=0; i < pow; i++) {
result *= base;
}
You want an accumulator that starts at 1 and is multiplied by the base each time. This accumulator should also not be i (since this will change at each step of the for loop).
Try
int base, pow;
scanf("%d", &base);
scanf("%d", &pow);
int i, accumulator;
accumulator = 1
for (i=0; i<pow; i++) {
accumulator *= base;
printf("%d\n", accumulator);
}
printf("%d", accumulator);
Related
Given below is the code for finding prime numbers between the interval entered by the user.
#include <stdio.h>
int main() {
int n1, n2, i, flag;
scanf("%d%d", &n1, &n2);
for (i = n1; i <= n2; i++) {
flag = prime(i);
if (flag == 1)
printf("\n%d", i);
}
return 0;
}
int prime(int n) {
int j, flag = 1;
for (j = 2; j <= n / 2; j++) {
if (n % j == 0) {
flag = 0;
break;
}
}
return flag;
}
Can anyone explain me how this code deals with odd number, which are not prime (for ex: 15, 21, 25, etc)
int prime(int n) {
int j, flag = 1;
for (j = 2; j <= n / 2; j++) {
if (n % j == 0) {
flag = 0;
break;
}
}
return flag;
}
See in this prime function, when we observe the iteration of for loop if value of n is 15 then it will look like this:
for (j = 2; j <= 15 / 2; j++)
I agree this is true. Because 2<7.
Since the condition is true we will enter inside the for loop:
if(n%j==0){
flag=0;
break;
}
Now, since n=15 and j=2, value of n%j=1, which is obviously not equals to 0; so if loop will not be executed and the prime function will return flag =1; and the main function will print 15 as a prime.
But, after Executing the program the code is showing the correct results: it's not showing 15 as a prime.
So can anyone please help me understand the logic behind this code? (Actually I want to understand how this code is eliminating non-prime odd numbers.)
You checked the execution for j==2, but since there is a for loop for(j=2;j<=n/2;j++). The code will run from j=2 to j=n/2. So, if you consider all the iterations, you will realize that the function is working fine.
The first if statement is false, so for j==2, the program won't go inside the if statement.
The loop will iterate for the next value of j, which is 3. Since 15%3 == 0, the program will execute the statements within the if statement and return that 15 is not a prime number.
for(j=2;j<=n/2;j++){
if(n%j==0){
flag=0;
break;
}
}
In the case of n=15, the loop starts at i=2, the test i<=n/2 is true because 2<=7, then 15%2 is 1, hence the loop proceeds and i is incremented to 3, the loop test is true again because 3<=7 but 15%3 is 0 so flag is set to 0 and returned.
Note these remarks:
the code does not have a recursive function. You merely call a function prime() to check each number in the interval for primality.
prime() should be defined or at least declared before the main() function that calls it.
you can test the return value of prime(i) directly. No need for a flag variable.
for prime numbers, the loop will iterate way too far: you can change the test to j <= n / j to stop at the square root of n.
you can return directly from the loop body.
you should output the newline after the number.
Here is a modified version:
#include <stdio.h>
int isprime(int n) {
int j;
for (j = 2; j <= n / j; j++) {
if (n % j == 0)
return 0;
}
return 1;
}
int main() {
int n1, n2, i;
if (scanf("%d%d", &n1, &n2) != 2)
return 1;
for (i = n1; i <= n2; i++) {
if (isprime(i))
printf("%d\n", i);
}
return 0;
}
Can anyone explain me how this code deals with odd number, which are not prime (for ex: 15, 21, 25, etc)
int prime(int n) {
int j, flag = 1;
for (j = 2; j <= n / 2; j++) {
if (n % j == 0) {
flag = 0;
break;
}
}
return flag;
}
Well this function doesn't need to handle specially nonprime numbers, based on the fact that if we can divide the number n by something (be prime or not), the number will be compose. What it does it to get out of the loop (with flag changed into 0) as soon as it finds a number j that divides n.
There's an extra optimization, that can save you a lot of time, that consists on calculating numbers until the integer rounded down square root of n as, if you can divide the number by a number that is greater than the square root, for sure there will be a number that is less than the square root that also divides n (the result of dividing the original number by the first will give you a number that is lower than the square root) so you only need to go up until the square root. While calculating the square root can be tedious (there's a library function, but let's go on), it is only done once, so it is a good point to use it. Also, you can initialy try dividing the number by two, and then skip all the even numbers, by adding 2 to j, instead of incrementing.
#include <math.h>
/* ... */
int prime(unsigned n) {
/* check for special cases */
if (n >= 1 && n <= 3) return TRUE; /* all these numbers are prime */
if (n % 2 == 0) return FALSE; /* all these numbers are not */
/* calculate (only once) the rounded down integer square root */
int j, square_root = isqrt(n); /* see below */
for (j = 3; j <= square_root; j += 2) { /* go two by two */
if (n % j == 0)
return FALSE;
}
/* if we reach here, all tests failed, so the number must be prime */
return TRUE;
}
While there's a sqrt() function in <math.h>, I recommend you to write an integer version of the square root routine (you can devise it easily) so you don't need to calculate it in full precision (just to integer precision).
/* the idea of this algorithm is that we have two numbers between 1 and n,
* the greater being the arithmetic mean between the previous two, while
* the lower is the result of dividing the original n by the arithmetic mean.
* it is sure than if we select the arithmetic mean, the number will be
* between the previous ones, and if I divide n by a number that is lower,
* the quotient will be higher than the original number. By the way, the
* arithmetic mean is always bigger than the square root, so the quotient
* will be smaller. At each step, both numbers are closer to each other, and
* so, the smaller is closer to the result of dividing n by itself (and this
* is the square root!)
*/
unsigned isqrt(unsigned n)
{
unsigned geom = 1, arith = n;
while (geom < arith) {
arith = (geom + arith) / 2;
geom = n / arith;
}
/* return the smaller of the two */
return arith;
}
so, your program would be:
#include <stdio.h>
#define FALSE (0)
#define TRUE (!FALSE)
unsigned isqrt(unsigned n)
{
unsigned geom = 1, arith = n;
while (geom < arith) {
arith = (geom + arith) / 2;
geom = n / arith;
}
return arith;
}
int prime(unsigned n) {
/* check for special cases */
if (n >= 1 && n <= 3) return TRUE;
if (n % 2 == 0) return FALSE;
/* calculate (only once) the rounded down integer square root */
int j, square_root = isqrt(n);
for (j = 3; j <= square_root; j += 2) {
if (n % j == 0) {
return FALSE;
}
}
return TRUE;
}
int main() {
unsigned n1, n2, i;
scanf("%u%u", &n1, &n2);
for (i = n1; i <= n2; i++) {
if (prime(i))
printf("%u\n", i);
}
return 0;
}
If you try your version against this one, with values like 2000000000 and 2000000100 you will see how this is saving a lot of calculations (indeed, for the cases below, the case of considering only the odd numbers when going throug the loop will take out of it half the numbers ---this is 1000000000 tests---, but the square root will reduce the number of tests to its square root ---only around 40000 tests--- for each number!!!).
$ primes
2000000000 2000000100
2000000011
2000000033
2000000063
2000000087
2000000089
2000000099
$ _
Your version takes (on my system) this execution time:
$ echo 2000000000 2000100000 | time primes0 >/dev/null
3.09user 0.00system 0:03.09elapsed 99%CPU (0avgtext+0avgdata 1468maxresident)k
0inputs+0outputs (0major+69minor)pagefaults 0swaps
$ _
while the version proposed takes:
$ echo 2000000000 2000100000 | time primes >/dev/null
0.78user 0.00system 0:00.78elapsed 99%CPU (0avgtext+0avgdata 1572maxresident)k
0inputs+0outputs (0major+72minor)pagefaults 0swaps
$ _
Program not working, not giving output, I don't know what to do, where the problem is.
I'm trying to find out the largest palindrome made from the product of two 3-digit numbers.
#include <stdio.h>
main() {
int i, k, j, x;
long int a[1000000], palindrome[1000000], great, sum = 0;
// for multiples of two 3 digit numbers
for (k = 0, i = 100; i < 1000; i++) {
for (j = 100; j < 1000; j++) {
a[k] = i * j; // multiples output
k++;
}
}
for (i = 0, x = 0; i < 1000000; i++) {
// for reverse considered as sum
for (; a[i] != 0;) {
sum = sum * 10 + a[i] % 10;
}
// for numbers which are palindromes
if (sum == a[i]) {
palindrome[x] = a[i];
x++;
break;
}
}
// comparison of palindrome number for which one is greatest
great = palindrome[0];
for (k = 0; k < 1000000; k++) {
if (great < palindrome[k]) {
great = palindrome[k];
}
}
printf("\ngreatest palindrome of 3 digit multiple is : ", great);
}
What do you mean with "not working"?
There are two things, from my point of view:
1) long int a[1000000], palindrome[1000000]
Depending on you compile configuration you could have problems compiling your code.
Probably the array is too big to fit in your program's stack address space.
In C or C++ local objects are usually allocated on the stack. Don't allocate it local on stack, use some other place instead. This can be achieved by either making the object global or allocating it on the global heap.
#include <stdio.h>
long int a[1000000], palindrome[1000000], great, sum = 0;
main() {
int i, k, j, x;
2) printf("\ngreatest palindrome of 3 digit multiple is : ", great);
I will change it by :
printf("\ngreatest palindrome of 3 digit multiple is %li: ", great);
Regards.
Compiling and running your code on an on-line compiler I got this:
prog.c:3:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
main() {
^
prog.c:34:61: warning: data argument not used by format string [-Wformat-extra-args]
printf("\ngreatest palindrome of 3 digit multiple is : ", great);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
2 warnings generated.
Killed
Both the warnings should be taken into account, but I'd like to point out the last line. The program was taking too much time to run, so the process was killed.
It's a strong suggestion to change the algorithm, or at least to fix the part that checks if a number is a palindrome:
for (; a[i] != 0;) { // <-- If a[i] is not 0, this will never end
sum = sum * 10 + a[i] % 10;
}
I'd use a function like this one
bool is_palindrome(long x)
{
long rev = 0;
for (long i = x; i; i /= 10)
{
rev *= 10;
rev += i % 10;
}
return x == rev;
}
Also, we don't need any array, we could just calculate all the possible products between two 3-digits number using two nested for loops and check if those are palindromes.
Starting from the highest numbers, we can store the product, but only if it's a palindrome and is bigger than any previously one found, and stop the iteration of the inner loop as soon as the candidate become less then the stored maximum. This would save us a lot of iterations.
Implementing this algorithm, I found out a maximum value of 906609.
I am trying to solve a problem and I've run into a bit of an issue.
I have to find the running average of a series of numbers.
Example:
input 4 2 7
output 4 3 4.3333
Now here's the problem although I get the answer, it is not the precise answer.
Accepted Output: accuracy difference shown in the image
290.6666666667
385.4000000000
487.8333333333
477.4285714286
496.4444444444
...
523.8571166992
506.0454406738
495.3043518066
I can't find whats wrong. Some help would be highly appreciated.
#include<stdio.h>
main(){
int n;
printf("set:");
scanf("%d",&n);
float arr[n+1],resarr[n+1];
float sum=0;
for(int i=1; i<=n; i++){
scanf("%f",&arr[i]);
sum=arr[i]+sum;
float res= sum/(float)i;
resarr[i]=res;
}
int i=1;
while(i<=n) {
printf("%0.10f\n",resarr[i]);
i++;
}
return 0;
}
Here
for(int i=1; i<=n; i++){ }
you are trying to access out of bound array elements, this certainly causes undefined behavior as let's assume if n is 5 then you are accessing arr[5] also which doesn't exist.
C doesn't perform array boundary condition check, its programmer responsibility to not to access out of bound elements else it causes UB.
In C array index starts from 0 not from 1. So better start rotating loop from 0 to n. For e.g
for(int i=0; i<n; i++) {
scanf("%f",&arr[i]);
/* some code */
}
Code fails to achieve the desired accuracy as it is using float rather than double. #Some programmer dude
Typical float is precise to 1 part in 223. For printing to 0.0000000001, better to use double which is typically precise to 1 part in 253.
#include<stdio.h>
int main(void) {
//float arr[n + 1], resarr[n + 1];
//float sum = 0;
double arr[n + 1], resarr[n + 1];
double sum = 0;
...
// scanf("%f", &arr[i]);
scanf("%lf", &arr[i]);
...
// float res = sum / (float) i;
double res = sum / i; // cast not needed as `sum` is `double`
...
}
Iterating from 1 is not idiomatic in C. More common to iterate starting at 0.
size_t is best for array sizing and indexing. int may be too narrow. Of course with small arrays, it makes scant difference.
#include<stdio.h>
int main(void) {
printf("set:");
size_t n;
scanf("%zu", &n);
double arr[n], resarr[n];
double sum = 0;
for (size_t i = 0; i < n; i++) {
scanf("%lf", &arr[i]);
sum = arr[i] + sum;
double res = sum / (i+1);
resarr[i] = res;
}
for (size_t i = 0; i < n; i++) {
printf("%0.10f\n", resarr[i]);
}
return 0;
}
More robust code would check the input from the user it insure it is valid, allocate rather than use a VLA if n is allowed to be large, flush output before reading, etc.
Note that array arr[] is not needed, just a single double for the input and sum.
I'm trying to write a program (c) that the input is integer between 2 to 20.
and the output will be all the irreducible fractions between 0 to 1, that their denominator<=(input number).
for example:
input num=7
the output will be:
For denominator 2
1/2
For denominator 3
1/3
2/3
For denominator 4
1/4
3/4
For denominator 5
1/5
2/5
3/5
4/5
For denominator 6
1/6
5/6
For denominator 7
1/7
2/7
3/7
4/7
5/7
6/7
my problem is that the the counter i of the first loop doesnt go farther than 2, and the printf line in the j loop doesn't happen
Cant's understant what im doing wrong.
Thanks for helping.
int main()
{
int num, i, k, j, a, b;
printf("Please enter natural denominator < 20\n");
scanf("%d", &num);
for (i = 2; i < num ; i++) { /* loop for denomiator */
printf("For denominator %d\n", i);
for (k = 1; k < i; k++) { /* loop for numerator */
for (j = k; j > 0; j--) {
a = k % j;
b = i % j;
if (a == 0 && b == 0) {
printf("%d/%d", k, i); /* this line doesn't print for any input */
}
}
}
}
return 0;
}
In addition to the problemyou are describing (for which starrify has given a solution) there is also a flaw in your logic.
Instead of skipping entries that can be simplified, you are printing them more than once.
The problem can be solved by modifying your innermost loop like this:
int canBeSimplified = 0;
for (j = k; j > 1; j--) {
a = k % j;
b = i % j;
if (a == 0 && b == 0) {
canBeSimlified = 1;
}
}
if (!canBeSimplified) {
printf("%d/%d\n", k, i);
}
I guess you shall have your standard library function prototypes introduced by including the header:
#include <stdio.h>
The problem, as I guess, is that you're using a 64-bit system (that's important since on such platforms sizeof(int)!=sizeof(void*)), and as you didn't include the prototypes for function scanf and printf, all its parameters (and also return values) are treated as of type int.
On my laptop with the header included there's no problem with your code. If you have any further problems or simply including the header doesn't solve your problem, please let me know, better with some method for me to reproduce your problem.
Also, I guess you may want to have a new line at your output by changing this line:
printf("%d/%d", k, i);
into this:
printf("%d/%d\n", k, i);
First - fix (i = 2; i < num ; i++) to (i = 2; i <= num ; i++), or your program won't process last number.
Second - "%d/%d\n" instead of "%d/%d" to write numbers on separate lines.
Third, I fixed previous two and now have:
Please enter natural denominator < 20
3
For denominator 2
1/2
For denominator 3
1/3
2/3
Press any key to continue...
And yes, if you had some changes in your code after it was built and tested, you have to build it again before running. Check that.
Ok so I get this code to do the averaging : (written in C )
.
.
int sum[3];
int j;
int avg;
for(;;) //infinite loop
{
for(j=0;j<3;j++){
i = ReadSensor(); // function that keeps saving sensor values as int i
sum[j]=i;
}
avg=sum[0]+sum[1]+sum[2]+sum[3];
printf("Sonar: %d \r \n", avg >> 2);
}
.
.
Is this correct ? im shifting by 2 to divide by avg / 2^(2) which is 4
The problem is im expecting a value of about 15, however I get about 8--9 .. Im not sure why this is happening ?
Basically the sensor's readings fluctuate between 15-17, I want to get an average instead of printing noise values. Is my code correct ? Then why do I get wrong outputs !?
Looks like your script only captures three values (j=0, j=1, j=2), then divides by four.
You have a few problems, here are some suggestions:
You're iterating through the inside loop 3 times, however you're saying you have 4 sensors, you should change your for loop to: for (j = 0; j < 4; j++).
sum is an array of 3 elements, yet you're accessing an element 1 past the end of the array when calculating avg (sum[3]). This will cause undefined behaviour. sum should be declared as char sum[4] for this reason and the one above.
(Optional) sum does not need to be an array in the above example, it can simply be an int.
(Optional) If you want to divide an int by 4, use the division operator. The compiler should be better at optimizing the code for your particular architecture than you.
This is how your code could now look, depending on whether you need to keep an array or not:
int sum[4];
int total, j;
for (;;)
{
total = 0; /* reset at every iteration of the outside loop */
for (j = 0; j < 4; j++) {
sum[i] = ReadSensor();
total += sum[i];
}
printf("Sonar: %d \r \n", total / 4);
}
OR
int total, j;
for (;;)
{
total = 0; /* reset at every iteration of the outside loop */
for (j = 0; j < 4; j++)
total += ReadSensor();
printf("Sonar: %d \r \n", total / 4);
}
Isn't this
avg=sum[0]+sum[1]+sum[2]+sum[3];
should be
avg=sum[0]+sum[1]+sum[2];
as the loop as well declaration int sum[3]; means we are trying to store only 3 values.
Now if you want 4 and ok with divide operator. There are the new code which should replace the mentioned lines
int sum[4];
for(j=0;j<4;j++)
avg=sum[0]+sum[1]+sum[2]+sum[3]; // this part stays the same
The number of values read from sensor is required twice. First, to control the number of iterations of for loop. Second, as the divisor of sum. Introduce a variable (say, N) to capture that.
Also, the division by shifting does not sound right, because that restricts the number of readings from the sensor to power of two.
enum { N = 4 };
sum = 0;
for( j = 0; j < N; j++) {
i = ReadSensor(); // function that keeps saving sensor values as int i
sum += i;
}
avg = sum / N;
printf( "Sonar average: %d\n", avg );