Number doesn't print in expected way - c

This is my program on 'Sin Calculator'
#include <stdio.h>
#include <math.h>
#define PI 3.1416
void fraction(double x, int y);
void print(double sx, int x, int y, int s);
void scal();
int main(){
scal();
return 0;
}
void fraction(double x, int y){
int b = 100, a;
a = x * 100;
while ((a % 2 != 0) || (a % 5 != 0)){
if (a % 2 == 0){
a /= 2;
b /= 2;
}
else if (a % 5 == 0){
a /= 5;
b /= 5;
}
}
print(x, a, b, y);
}
void print(double sx, int x, int y, int s){
printf (" Sin(%d) = %d/%d || %.2lf\n",s,x,y,sx);
scal();
}
void scal(){
double sine, sinx;
int x, a, b;
printf ("\n Sin(X) : ");
scanf ("%d",&x);
sinx = x * (PI / 180);
sine = sin(sinx);
fraction(sine, x);
}
I don't get any errors. But when i run it, though the variable 'a' of fraction function can be divided by 5 or 2, it doesn't do it. As a result I get the whole value of 'a'. For example, the value of Sin30 degrees is 0.50, so multiplying it with 100 makes 'a' 50. 50 is dividable by 2 and 5. But in fraction function, it seems that 'a' doesn't get divided there. As a result in 'print' function, i get '50/100' instead of '1/2'. Why is this happening? And also when i enter somethin like Sin23, the program doesn't finish. It stops. What's the problem?

while ((a % 2 != 0) || (a % 5 != 0))
this test fails for the value of 50 or any integer that is multiple of both 2 an 5. Therefore the while loop will not be entered and no division will occur, so a conserves its value.
maybe your intent was the inverse of the condition:
while ((a % 2 == 0) || (a % 5 == 0))

Related

Reverse the output of printf function in while loop

I wrote a code for a b-adic representation of a chosen number.
#include <stdio.h>
int b_adisch (int a, int b)
{
int x, y, mod, mod1;
x = a / b;
mod1 = a % b;
printf("%i\n", mod1);
do {
y = x / b;
mod = x % b;
x = y;
printf("%i\n", mod);
} while(x != 0);
return a ;
}
int main (void)
{
int a, b;
printf("pls input a ");
scanf("%i", &a);
printf("pls input b ");
scanf("%i", &b);
b_adisch(a, b);
return 0;
}
The output order will be reversed
since the printf has to be put into the while loop and the calculation starts with the last number of the representation.
Example if a = 10 and b = 2
The output is 0101
but it should be 1010
How can I change my code to make this happen?
How can i change my code to make this happen?
2 approaches:
Compute the digits from least to most significant and save in a adequate sized buffer. This is similar to OP's approach yet saves the results of each digit's computation for later printing.
#include <assert.h>
#include <limits.h>
void b_adisch(int value, int base) {
// Let us work with simple cases first.
assert(value >= 0);
assert(base >= 2 && base <= 10);
// Adequate sized buffer
char buffer[sizeof value * CHAR_BIT + 1];
// Start at end
char *end = &buffer[sizeof buffer - 1];
*end = '\0';
do {
end--;
int digit = value%base; // Find least digit
value /= base;
*end = digit + '0'; // save the digit as text
} while (value);
printf("<%s>\n", end); // print it as a string
}
Use recursion. A more radical change; This computes and prints the output of the more significant digits first.
void b_adischR_helper(int value, int base) {
// If the value is at least 2 digits, print the most significant digits first
if (value >= base) {
b_adischR_helper(value/base, base);
}
putchar(value % base + '0'); // Print 1 digit as text
}
void b_adischR(int value, int base) {
// Let us work with simple cases first.
assert(value >= 0);
assert(base >= 2 && base <= 10);
printf("<");
b_adischR_helper(value, base);
printf(">\n");
}
Test
int main() {
b_adisch(10, 2);
b_adischR(10, 2);
b_adisch(INT_MAX, 10);
b_adischR(INT_MAX, 10);
b_adisch(INT_MAX, 2);
b_adischR(INT_MAX, 2);
}
Output
<1010>
<1010>
<2147483647>
<2147483647>
<1111111111111111111111111111111>
<1111111111111111111111111111111>
You can store the output in an array as here it is stored in "arr" and later print the output in reverse order (from end to start).
#include <stdio.h>
int arr[10000]={0};
void b_adisch (int a, int b)
{
int x, y, mod, mod1,i=0,j;
x = a / b;
mod1 = a % b;
arr[i++]=mod1;
do {
y = x / b;
mod = x % b;
x = y;
arr[i++]=mod;
} while(x != 0);
for(j=i-1;j>=0;j--)
printf("%i\n",arr[j]);
}
int main (void)
{
int a, b;
printf("pls input a ");
scanf("%i", &a);
printf("pls input b ");
scanf("%i", &b);
b_adisch(a, b);
return 0;
}

How would you use the while statement to find the square root using the while loop

I have to write a program that will find a square root using the while loop. I was given this new_guess = (old_guess + (n / old_guess)) / 2.0; but I dont fully understand what to do with it, this is what I have:
int main(void)
{
double n, x, new_guess, old_guess, value;
printf("Enter a number:");
scanf("%lf", &n);
x = 1.00000;
while (new_guess >= n) {
new_guess = (old_guess + (n / old_guess)) / 2.0;
printf("%10.5lf\n", fabs(new_guess));
}
return 0;
}
x is the initial guess. Im really lost on how to do it. This is C also. I know its really wrong but I really dont understand how to make it start because when I enter a number it just stop right away.
Your program has undefined behavior because both new_guess and old_guess are uninitialized when you enter the loop.
The condition is also incorrect: you should stop when new_guess == old_guess or after a reasonable maximum number of iterations.
Here is a modified version:
#include <math.h>
#include <stdio.h>
int main(void) {
double n, x;
int i;
printf("Enter numbers:");
while (scanf("%lf", &n) == 1 && n >= 0.0) {
x = 1.0;
/* Using a while loop as per the assignment...
* a for loop would be much less error prone.
*/
i = 0;
while (i < 1024) {
double new_guess = (x + (n / x)) / 2.0;
if (new_guess == x)
break;
x = new_guess;
i++;
}
printf("%g: %.17g, %d iterations, diff=%.17g\n",
n, x, i, sqrt(n) - x);
}
return 0;
}
Given the start value, the number of iterations grows with the size of n, exceeding 500 for very large numbers, but usually less than 10 for small numbers. Note also that this algorithm fails for n = 0.0.
Here is a slightly more elaborate method, using the floating point break up and combine functions double frexp(double value, int *exp); and double ldexp(double x, int exp);. These functions do not perform any calculation but allow for a much better starting point, achieving completion in 4 or 5 iterations for most values:
#include <math.h>
#include <stdio.h>
int main(void) {
double n, x;
int i, exp;
printf("Enter a number:");
while (scanf("%lf", &n) == 1 && n >= 0.0) {
if (n == 0) {
x = 0.0;
i = 0;
} else {
frexp(n, &exp);
x = ldexp(1.0, exp / 2);
for (i = 0; i < 1024; i++) {
double new_guess = (x + (n / x)) / 2.0;
if (new_guess == x)
break;
x = new_guess;
}
}
printf("%g: %.17g, %d iterations, diff=%.17g\n",
n, x, i, sqrt(n) - x);
}
return 0;
}

CS50 PSET1 Greedy - Assignment error and using modulo ( C )

I am getting an error when compiling this code. Z is the final count of coins needed to make change with aim being to use minimum number of coins. I defined int Z = 0 near the top. I've tried adding int z again and changing type to f in print statement but no luck.
Here's the error:
error: format specifies type 'int' but the argument has type '<dependent type>' [-Werror,-Wformat]
greedy.c:77:16: error: use of undeclared identifier 'z'
printf("%i\n", z);
Here is my code. I am a beginner so any suggestions or corrections would be welcome.
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void)
{
//prompt user for amount of change owed
float f;
int num; //amount of change
do
{
printf("O hai! How much change is owed?:\n");
f = get_float();
}
while (f < 0); //verify input is positive
num = round(f * 100); //rounds float
//commence making change
do{
int c, e, i, j;
int z = 0; //z = coins
if (num % 25 == 0) // verifies that num is divisible by 25 so only 25c coins necessary
{
z = (num/25) + z; // updates final number of 25c coins
}
else if (num % 25 > 0)
{
i = num / 25;
j = num % 25;
}
else if ((num / 25 < 0) || (num >=10 && num < 25)) //this means that f is less than 25 cents so has to be divided by 10 cent coins
{
num = c;
c = j + c; //add remainder of num to the number to start with
}
if (c % 10 == 0) // c is less than 25c but divisible by 10c pieces
{
z = (c / 10) + z; //d is the final number of 10c coins
}
else if (c /10 < 1) //this means it's less than 10c
{
c = e; // Then c must be less than 10c
}
else if (e % 5 == 0) // divisible by 5c pieces
{
z = (e / 5) + z; // g is the number of 5 cent pieces
}
else if (e % 5 < 0)
{
z = (e / 1) + z; //h is the number of pennies
}
}
while (num > 0); //num is rounded float
printf("%i\n", z);
}
Firstly, I suggest you should format your code properly with indents.
Then, the cause of error is that z is declared inside the block associated to do loop and printf("%i\n", z); is out of its scope.
To get rid of this error, declare z at the place where visible from the printf() call -- for example, just before the do loop.
Note that declaring int Z = 0 won't work because identifiers' names are case-sensitive in C.
Like already said, you are declaring z inside the do-while loop, so it's visible only inside the loop.
You should declare it before the loop starts, so you can use it after the loop ends as well. Like this:
int z = 0; //z = coins
do{
***YOUR CODE***
} while();

Any reason why a loop wouldn't terminate even with an 'i' limiting value of repeats?

I'm doing this assignment for college in C, should be fairly simple, but a loop in it doesn't seem to terminate so the code won't work properly; even if I put in an i value to limit the amount of times it loops. Tried it with a for loop too, still gets stuck.
The code is supposed to take in values of coefficients and try to work out a root for a cubic equation by finding the midpoint between two large values and trying that out to see if it gets 0, if it doesn't, it should change one of the limits to the midpoint value. Here's the relevant code:
int main (void)
{
int i, u=1000, l=-1000;
float a, b, c, d, mid, y;
scanf(" %f %f %f %f", &a, &b, &c, &d);
while (abs(u - l) > 0.001 && i < 10)
{
mid= (u + l)/2;
y = a * pow(mid, 3) + b* pow(mid, 2) + c * mid + d;
if(y == 0) break;
else if(y < 0) l = mid;
else u = mid;
i++;
}
printf("\nThere is a root at: x = %.3f\n", mid);
}
Any help would be appreciated, thanks!
edit: Oh my god I'm an idiot. Always the small things. The code still isn't working but at least it's not stuck anymore, thanks guys!
You declared i, but did not initialize it, so it is set to whatever random value was left in memory.
For this example, lets say that value was -12,345.
Then i can be incremented over 12,000 times before it is greater than 10!
Your loop will run when i is incremented 12,355 times, and its value becomes 10, and the test i < 10 finally fails.
To fix this, initialize i = 0:
int i=0;
2 things. Initialize i to 0. this will ensure it terminates after 10 loops.
More important for your problem though, you have declared u and l as integers, I think you need to declare them as floats.
You need to initialize i: int i = 0;
This should work for you! You need to initialize i.
#include <stdio.h>
#include <math.h>
int main (void)
{
int i = 0, u = 1000, l =- 1000;
float a, b, c, d, mid, y;
scanf(" %f %f %f %f", &a, &b, &c, &d);
while (abs(u-l)>0.001 && i<10)
{
mid = (u + l)/2;
y = a*pow(mid,3) + b* pow(mid,2) + c*mid + d;
if(y == 0)
break;
else if(y<0)
l = mid;
else
u = mid;
i++;
}
printf("\nThere is a root at: x = %.3f\n", mid);
}
If you make u and l be floats then your while-loop terminates without i. Before that, abs(u-l) where u-l are ints will only terminate if a root is at zero. You also need to use fabs() instead of abs():
int main (void)
{
float u=1000.0, l=-1000.0;
float a, b, c, d, mid, y;
scanf(" %f %f %f %f", &a, &b, &c, &d);
while (fabs(u - l) > 0.001)
{
mid= (u + l)/2.0;
y = a * pow(mid, 3) + b* pow(mid, 2) + c * mid + d;
if(y == 0) break;
else if(y < 0) l = mid;
else u = mid;
}
printf("\nThere is a root at: x = %.3f\n", mid);
}
Seems like you still have something wrong in the bisection algorithm condition when you reset l and u to mid. I'm attaching a fixed version, and I used different variable names (sorry) to keep my head clear:
#define NMAX 1000
#define TOL 0.00001
int sign( float x ) {
if (x > 0.0) return 1;
if (x < 0.0) return -1;
return 0;
}
int main (void)
{
int n=0;
float fa, fc, b=1000.0, a=-1000.0;
float p3,p2,p1,p0,c;
scanf(" %f %f %f %f", &p3, &p2, &p1, &p0);
while(n<NMAX)
{
c = (a + b)/2.0;
fc = p3*pow(c, 3) + p2*pow(c, 2) + p1*c + p0;
if(fc == 0.0 || (b-a)/2.0 < TOL ) break;
fa = p3*pow(a, 3) + p2*pow(a, 2) + p1*a + p0;
if( sign(fc) == sign(fa) )
a = c;
else
b = c;
n++;
}
if(n==NMAX) {
printf("Method failed.\n");
}
else {
printf("\nThere is a root at: x = %.3f\n", c);
}
}

Conveying a formula in C (% is)

So I have to make this formula "y = y / (3/17) - z + x / (a % 2) + PI" in C
I am having a problem with (a%2) as it is returning odd values. ie 1%2 = 0.000001
int assignment7()
{
#define PI 3.14
int a=0,amod2;
double Ny=0,y=0,z=0,x=0;
printf("Enter values for x,y,z and a: ");
scanf("%d%lf%lf%lf",&a,&y,&z,&x);
//printf("%d,%lf,%lf,%lf\n",a,y,z,x);
//amod2=1%2;
//printf("%lf",amod2);
Ny=y/(double)(3/17) - z+x / amod2 + PI;
printf("%lf\n",Ny);
When you say:
printf("%lf",amod2);
the compiler expects amod2 to be a "long float" (aka a double), but you defined it as:
int amod2;
Also your prompt says "x,y,z and a" but you read in the order "a,y,z,x":
printf("Enter values for x,y,z and a: ");
scanf("%d%lf%lf%lf",&a,&y,&z,&x);
that's awkward at best.
EDIT: cleaned up a bit and made some assumptions about order of operations:
#include <stdio.h>
#define PI 3.14
#define DIVSOR (3.0/17.0)
int assignment7 ( void );
int assignment7 ( void ) {
double x = 0.0;
double y = 0.0;
double z = 0.0;
int a = 0;
int amod2;
double Ny;
printf("Enter values for x,y,z and a: ");
scanf("%lf%lf%lf%d",&x,&y,&z,&a);
amod2 = a % 2;
Ny = (y / DIVSOR) - z + (x / amod2) + PI;
printf("%lf\n", Ny);
return 0;
}
int main ( void ) { return assignment7(); }
You don't say what inputs you are giving it, (a test case with inputs and the expected results would be super helpful), but I can point out that x / (a % 2) is going to be infinity when a is 2 or 4 or 6 or ...

Resources