Reading double values in "Scanf" statement - c

I wrote a program for finding a root of a fifth degree polynomial, in a range that the user decides as an input.
for example:
Please enter the coefficients of the polynomial:
-64 0 0 0 0 2
Please enter the range:
4 -5.7
Invalid range! Please enter the range:
2 3.5
The polynomial has a root: x=2.
My problem is in when I enter for example the range **10.4 10.2" the program can't compare between two values and decide that its an invalid range. For integers it works.
How do I fix this?
#include <stdio.h>
#define ZERO 0.00001
int main()
{
double a_0,a_1,a_2,a_3,a_4,a_5,end_of_range,beginning_of_range;
int x,root;
printf("Please enter the coefficients of the polynomial:\n");
scanf("%lf%lf%lf%lf%lf%lf", &a_0, &a_1, &a_2, &a_3, &a_4, &a_5);
printf("Please enter the range:\n");
scanf("%lf%lf", &beginning_of_range, &end_of_range);
while (beginning_of_range >= end_of_range)
{
printf("Invalid range! Please enter the range:\n");
scanf("%lf%lf", &beginning_of_range, &end_of_range);
}
x = beginning_of_range;
while (x <= end_of_range)
{
if ((a_0 + a_1*x + a_2*x*x + a_3*x*x*x + a_4*x*x*x*x + a_5*x*x*x*x*x >= -ZERO)
&& (a_0 + a_1*x + a_2*x*x + a_3*x*x*x + a_4*x*x*x*x + a_5*x*x*x*x*x <= ZERO))
{
root = x;
printf("The polynomial has the root x=%d.", root);
break;
}
x++;
if( x > end_of_range)
{
printf("Could not find a root.");
break;
}
}
return 0;
}
Note: I want the roots to be only Integers! that's why I declared x as an int.
And something strange is happening, when I enter the range [10.4, 10.3] it just wait for about 1 minute and then prints "Could not find a root", although it must print invalid range.

Things to change:
Change the type of x. Instead of
int x;
use
double x;
Declare root as a variable.
double root;
Fix the format used to print root. Instead of
printf("The polynomial has the root x=%d.", root);
use
printf("The polynomial has the root x=%lf.\n", root);

Make x a double, but let it only take on integer values.
// x = beginning_of_range;
x = ceil(beginning_of_range);
// while (x <= end_of_range)
while (x <= floor(end_of_range))
// x++
x += 1.0;
This approach will have trouble when |x| is large (about 1/DBL_EPSILON) as x += 1.0; may not result in a incremented x.
BTW:
double y = ((((a_5*x + a_4)*x + a_3)*x + a_2)*x + a_1)*x + a_0;
// is numerically more stable (and likely faster) than
y = (a_0 + a_1*x + a_2*x*x + a_3*x*x*x + a_4*x*x*x*x + a_5*x*x*x*x*x;
Minor: Suggest removing = in range test. A range of [1 1] looks legitimate to me.
// while (beginning_of_range >= end_of_range)
while (beginning_of_range > end_of_range)

Related

A Program to print the last n, (n+1), (n+2),....(n+31) number of digits of the number input by the user, where n = 1, otherwise print "0+error.extra"

#include <stdio.h>
int main()
{
signed int x;
int x1 = 0, x2 = 10, final, loop = 1, y = 10, c;
printf("Enter the value of X.\n");
scanf("%d", &x);
printf("Value Scanned:%d\n", x);
again:
if (loop <= 32)
{
if (x >= x1 && x < x2)
{
final = x - x1;
printf("%d", final);
y = y * 10;
x1 = 0;
x2 = 0;
++loop;
goto again;
}
else
{
c = x2 - x1;
if (x1 == x2)
{
x2 += y;
goto again;
}
else if (c == y)
{
x1 += y;
x2 += y;
goto again;
}
else
{
printf("Error in Process");
goto ending;
}
}
}
else
{
printf("0+error, extra long input");
}
ending:
return 0;
}
Flowchart:
I am a beginner in C-language and only know how to use If-else, Switch, Goto statements, with basic knowledge of how to integrate basic level loops. So please tell me what/where I am wrong instead of telling me how to use arrays because I don't know them, etc. This is my most complex code until now.
Now for Explanation of Coding,
I wrote X1 as the lower value and X2 as the upper value while first keeping a difference = Y(initially 10) between them.
Continuously increasing the value of X1 and X2 by Y(10) together simultaneously, I will arrive in between an intersection where my x(input) lies.
Eg-
x=568
then X1 and X2 will keep on increasing until they reach X1 = 560 and X2 = 570, then they will do Final = X(568) - X1(560) and print it.
since it can only happen for 32-digits long, so I wrote loop = 0 and only processing my main statement till loop is smaller than or equal to 32, otherwise printing "0+error".
then I put Y = Y * 10 every time the value was within my specified range.
It should give me the values like Last digit, then last 2 digits, then last 3 digits,etc. but after scanning the value, it isn't exciting at all.
Evaluating what you are attempting to do, I reworked your code to make it a bit more structured without utilizing arrays at that seemed to be something you wanted to avoid at this time. However, these days, the use of the goto statement is usually avoided since functionality such as for loops, do/while loops, and while loops offer better clarity to coding. With that in mind, following is a snippet of code that provides the functionality it looks like you want.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x, x1, x2, y = 10, counter = 0, last_digit;
printf("Please enter a number: ");
scanf("%d", &x);
if (x < 0) /* Just in case a negative integer is entered */
{
x = x * -1;
}
while (1) /* Use a while loop with associated break statements to avoid goto and label statements */
{
x1 = 0;
x2 = 10;
counter += 1;
while (1)
{
if (x >= x1 && x <= x2)
{
last_digit = x - x1;
if (counter == 1)
{
printf("The last digit is: %d\n", last_digit);
}
else
{
printf("The next digit is: %d\n", last_digit);
}
break;
}
x1 += y;
x2 += y;
}
x = x / 10; /* Perform integer division by ten to get to the next digit in the entered number */
if (x == 0) /* Once all digits have been processed the outer while loop can be exited */
{
break;
}
}
return 0;
}
Following are some key points.
As noted, the loop process using goto statements is replaced by two while loops; one while loop nested inside another while loop.
Utilizing integer division by ten, each digit can be ascertained and printed.
Utilizing the nested while loops with break statements allows for a more compact program.
Utilizing this code snippet, following is a sample test from the terminal.
#Dev:~/C_Programs/Console/LastDigit/bin/Release$ ./LastDigit
Please enter a number: 479824385
The last digit is: 5
The next digit is: 8
The next digit is: 3
The next digit is: 4
The next digit is: 2
The next digit is: 8
The next digit is: 9
The next digit is: 7
The next digit is: 4
Back in the day, the goto statement had its place in coding, but today it is pretty much an artifact.
Give that a try and see if it meets the spirit of your project.

how to find which integer no is maximim out of given numbers

#include <stdio.h>
#include <stdlib.h>
int main()
{
int x, y, z, result, max;
printf("\nInput the first integer: ");
scanf("%d", &x);
printf("\nInput the second integer: ");
scanf("%d", &y);
printf("\nInput the third integer: ");
scanf("%d", &z);
result=(x+y+abs(x-y))/2;
max=(result+z+abs(result-z))/2;
printf("\nMaximum value of three integers: %d", max);
printf("\n");
return 0;
}
unable to understand the formula:
result=(x+y+abs(x-y))/2;
max=(result+z+abs(result-z))/2;
Looking at this expression:
(x+y+abs(x-y))/2
If x => y, then abs(x-y) is the same as x-y. That gives us: (x+y+(x-y))/2 == (x+x+y-y)/2 == 2x/2 == x.
If x < y, then abs(x-y) is the same as y-x. That gives us: (x+y+(y-x))/2 == (x-x+y+y)/2 == 2y/2 == y.
So the above expression evaluates to the larger of x and y without using any conditionals. The following expression (result+z+abs(result-z))/2 does the same thing with z and the max of x and y.
Note however that this method has the potential to cause overflow. The cleanest way to do this is to explicitly compare:
if (x >= y && x >= z) {
max = x;
} else if (y >= x && y >= z) {
max = y;
} else {
max = z;
}
then how to solveit – Ujjwal Bhardwaj 5 mins ago
int max(int a, int b, int c)
{
return a > b ? (a > c ? a : c) : (b > c ? b : c);
}
One way to visualize it is:
Imagine you have 2 trees. One is 16 meter tall and the other is 20 meter tall.
You look at their average, which is the “midpoint” and is 18 meter tall. Now, what’s their difference? 4 meter.
You take 18 and add half of that difference, is 20 (the max). Likewise, you can take the average and minus half of the difference and it is the min.
So,
average plus half the difference
= (x + y) / 2 + abs(x - y) / 2
= (x + y + abs(x - y)) / 2
The following line of code returns the value of whichever is greater, x or y.
result = (x + y + abs(x - y)) / 2;
By adding the absolute value of the difference between x and yto the sum of x and y you essentially get 2 times the larger number. For example, if x=5 and y=20 then abs(x - y) = 15. So 5 + 20 + 15 = 40 which is 2 times the larger number. Divide that by 2 and you have determined larger value. Then by repeating the formula with the result above and z you have calculated the largest of the three.

Validating a triangle in C

I'm new in C, so I try to create a program that calculate the area of triangle as a start.
Calculating the area is easy when the triangle exists, however the validation of straight line is working partially.
Example:
A(0,-4) B(1,0) C(4,12) does not produce straight line error.
but
A(4,12) B(1,0) C(0,-4) produce straight line error.
#include <stdio.h>
#include <math.h>
double square(double num){
return (num*num);
}
int main()
{
double x[5],y[5],a,b,c,angle,area;
printf("Hello there! Calculating the area of triangle.\n");
printf("Enter a coordinate A :\n");
scanf("%lf,%lf",&x[0],&y[0]);
printf("Enter another coordinate B :\n");
scanf("%lf,%lf",&x[1],&y[1]);
printf("Enter another coordinate C :\n");
scanf("%lf,%lf",&x[2],&y[2]);
// AB as base (a) , c is opposite side
a = sqrt( square((x[0]-x[1])) + square((y[0]-y[1])) );
b = sqrt( square((x[0]-x[2])) + square((y[0]-y[2])) );
c = sqrt( square(x[1]-x[2]) + square((y[1]-y[2])) );
double num = (square(a)+square(b)-square(c))/(2*a*b);
angle = acos(num);
area = .5*a*b*sin(angle);
//printf("%lf %lf %lf %lf %lf \n",a,b,c,num,angle);
if (num == 1 || num ==-1){
printf("That's a straight line.");
}else{
printf("Area of triangle is %lf\n",area);
}
return 0;
}
You can use a different test, and perhaps a different area formula. If you use Heron's formula, then once you have the lengths of the sides a, b, and c, you can compute:
double p = (a + b + c)/2;
double area = sqrt(p*(p-a)*(p-b)*(p-c));
You can detect if the triangle is valid by checking that p is greater than each of the sides.
double p = (a + b + c)/2;
if ((p > a) && (p > b) && (p > c)) {
double area = sqrt(p*(p-a)*(p-b)*(p-c));
printf("Area of triangle is %lf\n", area);
} else {
printf("I don't consider that a triangle.\n");
}
Try it online!
The problem in your code is double num = (square(a)+square(b)-square(c))/(2*a*b); gets evaluated to a number slightly larger than 1 in some cases. This can happen with floating point computations. In your case you can safely add if (num > 1) num = 1; after that line since cosine equation always will give you a value larger than 0 and less than 1 for triangles.
However there's a problem if two points overlap and a or b becomes zero. You will have to check for that and handle it as a special case if such input is expected by your code. (If two points overlap then they are collinear anyways. You can check the overlap by checking if any of a,b,c are zero)

Integration using the Trapezium Rule in C giving wrong answer for certain values

I've written some code to Integrate the function 5x^4 + 4x^3 + 3x^2 + 2x + 1.
#include<stdio.h>
#include<math.h>
float func(float x){
float a;
a = 5*pow(x,4) + 4*pow(x,3) + 3*pow(x,2) + 2*x +1;
return a;
}
int main(){
float numberOfXValues;
float a = 0; //lower limit
float b = 1; //upper limit
float numberOfStrips;
float stripSize;
float finalAnswer;
float sumFirstAndLast; //summation of first and last x value
while(1){
printf("Input number of X values:");
scanf("%f", &numberOfXValues);
numberOfStrips = numberOfXValues - 1;
stripSize = (b - a)/(numberOfStrips);
sumFirstAndLast = 0.5*func(a) + 0.5*func(b);
for (float z = stripSize; z < b; z += stripSize ){
sumFirstAndLast += func(z);
}
finalAnswer = sumFirstAndLast * stripSize;
printf("%f\n", finalAnswer);
}
return 0;
}
And it works for the majority of values, but the output for 13 and 20 is giving the wrong answer. I've looked through it a few times but can't see what could be causing this.
Input number of X values:10
5.039070
Input number of X values:11
5.031651
Input number of X values:12
5.026160
Input number of X values:13
6.271982
Input number of X values:14
5.018732
Input number of X values:15
5.016153
Input number of X values:16
5.014071
Input number of X values:17
5.012367
Input number of X values:18
5.010955
Input number of X values:19
5.009773
Input number of X values:20
5.798243
Input number of X values:21
5.007917
The problem is that in the exit condition of the inner loop, you compare two floating point numbers. After numberOfStrips iterations, it's not guaranteed that z == b because of floating point accuracy. It's entirely possible that z < b or z > b. In the z < b case, the loop it executed another time.
You should make numberOfStrips an integer and rewrite the loop like this:
float z = stripSize;
for (int i = 1; i < numberOfStrips; i++) {
sumFirstAndLast += func(z);
z += stripSize;
}
At a first glance this looks to precision and rounding issues of float.
Therefore change float to double.
For example on my machine I get 6.271982 for an input of 10 when using float while I get 5.021983 as result when using double.
Moreover you should use an epsilon in floating point comparisons.
Placing the line:
printf("%f, %d\n", z, z < b);
Inside the for loop will print the z values each iteration along with the loop condition result. The last output of this will be:
1.000000, 1
Which is pointing that we have already reached the right limit, but still performing the loop body. Literally it is thinking that 1.000 < 1.000. It can happen when working with float numbers, so in order to prevent it, consider looping on some integer number (numberOfXValues for example).

3-digit integer number program won't execute

Yes, this is a basic C coding homework problem. No, I am not just looking for someone to do it for me. Considering that this is my first programming class, I'm not surprised that I can't get it to work, and I'm certain there is plenty wrong with it. I just want some help pointing out the problems in my code and the things that are missing so that I can fix them on my own.
Homework Question:
Write a program to read ONLY one integer number (your input must be
one 3 digit number from 100 to 999), and to think of a number as
being ABC (where A, B, and C are the 3 digits of a number). Now,
form the number to become ABC, BCA, and CAB, then find out the
remainder of these three numbers when they are divided by 11.
Assume remainders would respectively be X, Y, and Z and add them
up as X+Y, Y+Z, and Z+X. Now if any of these summations is odd
number, increase it by 11 if the summation plus 11 is less than 20,
otherwise decrease the summation by 11 (this summation operation
must be positive number but less than 20). Finally, divide each
of the sums in half. Now, print out all the resulting digits.
My Code:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
//Declare all variables
int OrigNumber;
int x, y, z;
int number;
number = x, y, z;
int sum;
//
printf("Input a three digit number");
//
int c;
c = OrigNumber %10;
//
int b;
b=((OrigNumber - c) % 100)/10;
//
int a;
a = (OrigNumber - (b + c))/100;
//
int abc, bca, cab;
abc = (a*100) + (10*b) + c;
bca = (10*b) + c + (a*100);
cab = c + (a*100) + (10*b);
//
if((number % 2) == 1)
{
if(number + 11 < 20)
number += 11;
else if((100 - 11 > 0) && (100 - 11 < 20))
number -= 11;
}
//
x = abc/11;
y = bca/11;
z = cab/11;
//
sum = (x + y),
(y + z),
(z + x);
}
To start with, you need to read the input. Start with a prompt that includes a carriage return:
printf("Input a three digit number: \n");
Since it's a three digit number, you could add the following line to read the input:
scanf("%3d", &OrigNumber);
The next bit of code works quite well until you get to your if (number % 2) which is meaningless since you didn't really define number - well, you did, but the line
number = x, y, z;
does NOT do what you think it does. If you add
printf("So far I have abc=%d, bca=%d, cab=%d\n", abc, bca, cab);
after you first read in the number and computed those three, you will see you are well on your way.
Note that
number = x, y, z;
Uses a thing called the "comma operator". All the things (a,b,c) are "evaluated" but their values are not returned. At any rate, where you have that line, you didn't yet assign a value to x,y and z.
Is that enough to get your started?
update now that you have had a few hours to mull this over, here are a few more pointers.
Your computation of abc, cab, bca makes no sense. I will show you just one of them:
cab = c*100 + a*10 + b;
Next you need to compute each of x, y and z. Again, here is one of the three:
y = bca%11;
Now you have to make the sums - I call them xy, yz, and zx. Just one of them:
zx = z + x;
Next, to deal with the instruction: "Now if any of these summations is odd number, increase it by 11 if the summation plus 11 is less than 20, otherwise decrease the summation by 11:
if(xy % 2 == 1) {
if(xy + 11 < 20) xy += 11; else xy -= 11;
}
use similar code for all three sums. Then "divide by 2":
xy /= 2;
repeat as needed.
Finally, print out the result:
printf("xy: %d, yz: %d, zx: %d\n", xy, yz, zx);
The amazing thing is that if you did this right, you get the original numbers back...
You could make the code more compact by using an array of values and looping through it - rather than repeating the code snippets I wrote above with different variables. But I suspect that is well outside the scope of what you are expected to know at this point.
Can you take it from here?
#include <stdio.h>
int main()
{
//Declare all variables
int OrigNumber;
int a, b, c;
int abc, bca, cab;
int x, y, z;
int xplusy , yplusz, xplusz;
printf(" A program to read ONLY one integer number.\n Input must be one 3 digit number from 100 to 999 : ");
scanf("%d", &OrigNumber); // Get input from console
if(OrigNumber > 999 || OrigNumber < 100) {
printf("Invalid number. Quiting program. This is error handling. Important while learning programming.");
return 0;
}
c = OrigNumber %10; // digit at unit's place
b=((OrigNumber) % 100)/10; //digit at the ten's place
a = (OrigNumber)/100; //digit at the 100's place. Note: 734/100 = 7. NOT 7.34.
printf("\n Three numbers say A,B, C : %d, %d , %d ", a, b, c);
abc = a*100 + 10*b + c;
bca = 100*b + 10*c + a;
cab = c*100 + a*10 + b;
printf("\n Three numbers say ABC, BCA, CAB : %d, %d , %d ", abc, bca, cab);
x = abc % 11; // Reminder when divided by 11.
y = bca % 11;
z = cab % 11;
printf("\n Three numbers say X, Y, Z : %d, %d , %d ", x, y, z);
xplusy = x + y; // Adding reminders two at a time.
yplusz = y + z;
xplusz = x + z;
printf("\n Three numbers X+Y, Y+Z, X+Z : %d, %d , %d ", xplusy, yplusz, xplusz);
if((xplusy % 2) == 1) {
if(xplusy + 11 < 20)
xplusy += 11;
else
xplusy -= 11;
}
if((yplusz % 2) == 1) {
if(yplusz + 11 < 20)
yplusz += 11;
else
yplusz -= 11;
}
if((xplusz % 2) == 1) {
if(xplusz + 11 < 20)
xplusz += 11;
else
xplusz -= 11;
}
xplusy /= 2; // Finally, divide each of the sum in half.
yplusz /= 2;
xplusz /= 2;
printf("\n Now print out all the resulting digits : %d, %d , %d \n", xplusy, yplusz, xplusz);
return 0;
}
int abc, bca, cab;
abc = (a*100) + (10*b) + c;
bca = (10*b) + c + (a*100);
cab = c + (a*100) + (10*b);
I suggest printing out the numbers at this point in the code.
printf( "%d %d %d", abc, bca, cab );
I think you'll see one of the problems you need to solve.
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
int n, a, b, c, abc, bca, cab, x, y, z, p, q, r;
scanf("%d", &n);
c=n%10;
b=(n/10)%10;
a=n/100;
abc=a*100+b*10+c;
bca=b*100+c*10+a;
cab=c*100+a*10+b;
x=abc%11;
y=bca%11;
z=cab%11;
p=x+y;
q=y+z;
r=z+x;
return 0;
}
Now if any of these summations is odd number, increase it by 11 if the
summation plus 11 is less than 20, otherwise decrease the summation by
11 (this summation operation must be positive number but less than
20). Finally, divide each of the sums in half. Now, print out all the
resulting digits.
i didnt get the final part, can you explain it more clearly?

Resources