I'm trying to write a simple quadratic equation solver in C#, but for some reason it's not quite giving me the correct answers. In fact, it's giving me extremely large numbers as answers, usually well into the millions.
Could anyone please shed some light? I get the exact same answer for the positive root and the negative root as well. (Tried two different methods of math)
static void Main(string[] args)
{
int a;
int b;
int c;
Console.WriteLine("Hi, this is a Quadratic Equation Solver!");
Console.WriteLine("a-value: ");
try
{
a = int.Parse(Console.ReadLine());
Console.WriteLine("b-value: ");
b = int.Parse(Console.ReadLine());
Console.WriteLine("c-value: ");
c = int.Parse(Console.ReadLine());
Console.WriteLine("Okay, so your positive root is: " + quadForm(a, b, c, true));
Console.WriteLine("And your negative root is: " + quadForm(a, b, c, false));
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.ReadLine();
}
static int quadForm(int a, int b, int c, Boolean pos)
{
int x = 0;
if (pos)
x = ((-b + (int) (Math.Sqrt((b * b) - (4 * a * c)))) / (2 * a));
else
x = ((-Math.Abs(b) - (int) (Math.Sqrt(Math.Pow(b,2) - (4 * a * c)))) / (2 * a));
return x;
}
Try this version of quadForm:
static double quadForm(int a, int b, int c, bool pos)
{
var preRoot = b * b - 4 * a * c;
if (preRoot < 0)
{
return double.NaN;
}
else
{
var sgn = pos ? 1.0 : -1.0;
return (sgn * Math.Sqrt(preRoot) - b) / (2.0 * a);
}
}
Related
This question already has answers here:
Why does integer division in C# return an integer and not a float?
(8 answers)
Closed 2 years ago.
I need to complete a task - to implement a solution to a formula in C#, but the result in the console is not what I need. The result should be -11.84361, but the console outputs 15.1676628055975. What's wrong with the code? What to fix?
namespace Exercise10
{
class Program
{
static void Main()
{
Number number1 = new Number();
number1.Z();
Console.ReadKey();
}
}
class Number
{
double x, y, znamenatel, znamenatelh, virazhenie;
public void Z()
{
M:
Console.Write("Введите число x: ");
x = double.Parse(Console.ReadLine());
Console.Write("Введите число y: ");
y = double.Parse(Console.ReadLine());
znamenatelh = Math.Pow(Math.E, 2) - Math.Pow(x + y, 3 / 4);
if (znamenatelh < 0)
{
Console.WriteLine("Нельзя извлечь корень из отрицательного числа. Введите числа заново.");
goto M;
}
znamenatel = Math.Pow(znamenatelh, 1 / 3);
if (znamenatel == 0)
{
Console.WriteLine("Нельзя делить на нуль. Введите числа заново.");
goto M;
}
void Z_()
{
virazhenie = (x / znamenatel) + Math.Pow(Math.Pow(x - y, Math.Sin(x * y)) / znamenatel, 7 / 3);
Console.Write($"Z({x}, {y}) = {virazhenie}");
}
Z_();
}
}
} // <---- for some reason leaves the block
Here is all the information about the program and what should happen.
When you divide integer by integer the result is integer as well; in your case
3 / 4 == 0
1 / 3 == 0
7 / 3 == 2
In order to get floating point results (0.75, 0.33333, 2.33333) you should divide floating point values: 3.0 / 4.0, 1.0 / 3.0, 7.0 / 3.0:
// znamenatel' is Russian for "denominator"
znamenatelh = Math.Pow(Math.E, 2) - Math.Pow(x + y, 3.0 / 4.0);
...
// znamenatel' is Russian for "denominator"
znamenatel = Math.Pow(znamenatelh, 1.0 / 3.0);
...
// virazhenie is Russian for "formula" or "expression"
virazhenie = (x / znamenatel) + Math.Pow(Math.Pow(x - y, Math.Sin(x * y)) / znamenatel, 7.0 / 3.0);
Side note: goto M; is evil, turn
label M;
...
if (condition)
goto M;
construction into loop, e.g.
while (true) {
...
if (condition)
continue;
break;
}
Edit: Let's extract computation:
private static double Compute(double x, double y) {
if (x < y)
return double.NaN;
double denominator = Math.Exp(2) - Math.Pow(x + y, 3.0 / 4.0);
if (denominator == 0)
return x < 0 ? double.NegativeInfinity :
(x == 0) || (x == y) ? double.NaN :
double.PositiveInfinity;
denominator = Math.Pow(Math.Abs(denominator), 1.0 / 3.0) * Math.Sign(denominator);
double result = x / denominator;
double fraction = Math.Pow(x - y, Math.Sin(x * y)) / denominator;
result += Math.Pow(Math.Abs(fraction), 7.0 / 3.0) * Math.Sign(fraction);
return result;
}
UI (Simplified)
public void Z() {
double z = 0.0;
while (true) {
Console.WriteLine("Enter x: ");
double x = double.Parse(Console.ReadLine());
Console.WriteLine("Enter y: ");
double y = double.Parse(Console.ReadLine());
z = Compute(x, y);
if (!double.IsNaN(z) && !double.IsInfinity(z))
break;
Console.WriteLine("Invalid x and (or) y. Please, try again.");
}
Console.WriteLine(z);
}
Demo:
Console.Write(Compute(15, 5));
Outcome:
-11.8436193845787
So I have a problem that I'm stuck on it since 3 days ago.
You want to participate at the lottery 6/49 with only one winning variant(simple) and you want to know what odds of winning you have:
-at category I (6 numbers)
-at category II (5 numbers)
-at category III (4 numbers)
Write a console app which gets from input the number of total balls, the number of extracted balls, and the category, then print the odds of winning with a precision of 10 decimals if you play with one simple variant.
Inputs:
40
5
II
Result I must print:
0.0002659542
static void Main(string[] args)
{
int numberOfBalls = Convert.ToInt32(Console.ReadLine());
int balls = Convert.ToInt32(Console.ReadLine());
string line = Console.ReadLine();
int theCategory = FindCategory(line);
double theResult = CalculateChance(numberOfBalls, balls, theCategory);
Console.WriteLine(theResult);
}
static int FindCategory (string input)
{
int category = 0;
switch (input)
{
case "I":
category = 1;
break;
case "II":
category = 2;
break;
case "III":
category = 3;
break;
default:
Console.WriteLine("Wrong category.");
break;
}
return category;
}
static int CalculateFactorial(int x)
{
int factorial = 1;
for (int i = 1; i <= x; i++)
factorial *= i;
return factorial;
}
static int CalculateCombinations(int x, int y)
{
int combinations = CalculateFactorial(x) / (CalculateFactorial(y) * CalculateFactorial(x - y));
return combinations;
}
static double CalculateChance(int a, int b, int c)
{
double result = c / CalculateCombinations(a, b);
return result;
}
Now my problems: I'm pretty sure I have to use Combinations. For using combinations I need to use Factorials. But on the combinations formula I'm working with pretty big factorials so my numbers get truncated. And my second problem is that I don't really understand what I have to do with those categories, and I'm pretty sure I'm doing wrong on that method also. I'm new to programming so please bare with me. And I can use for this problem just basic stuff, like conditions, methods, primitives, arrays.
Let's start from combinatorics; first, come to terms:
a - all possible numbers (40 in your test case)
t - all taken numbers (5 in your test case)
c - category (2) in your test case
So we have
t - c + 1 for numbers which win and c - 1 for numbers which lose. Let's count combinations:
All combinations: take t from a possible ones:
A = a! / t! / (a - t)!
Winning numbers' combinations: take t - c + 1 winning number from t possible ones:
W = t! / (t - c + 1)! / (t - t + c - 1) = t! / (t - c + 1)! / (c - 1)!
Lost numbers' combinations: take c - 1 losing numbers from a - t possible ones:
L = (a - t)! / (c - 1)! / (a - t - c + 1)!
All combinations with category c, i.e. with exactly t - c + 1 winning and c - 1 losing numbers:
C = L * W
Probability:
P = C / A = L * W / A =
t! * t! (a - t)! * (a - t)! / (t - c + 1)! / (c - 1)! / (c - 1)! / (a - t- c + 1)! / a!
Ugh! Not let's implement some code for it:
Code:
// double : note, that int is too small for 40! and the like values
private static double Factorial(int value) {
double result = 1.0;
for (int i = 2; i <= value; ++i)
result *= i;
return result;
}
private static double Chances(int a, int t, int c) =>
Factorial(a - t) * Factorial(t) * Factorial(a - t) * Factorial(t) /
Factorial(t - c + 1) /
Factorial(c - 1) /
Factorial(c - 1) /
Factorial(a - t - c + 1) /
Factorial(a);
Test:
Console.Write(Chances(40, 5, 2));
Outcome:
0.00026595421332263435
Edit:
in terms of Combinations, if C(x, y) which means "take y items from x" we
have
A = C(a, t); W = C(t, t - c + 1); L = C(a - t, c - 1)
and
P = W * L / A = C(t, t - c + 1) * C(a - t, c - 1) / C(a, t)
Code for Combinations is quite easy; the only trick is that we return double:
// Let'g get rid of noisy "Compute": what else can we do but compute?
// Just "Combinations" without pesky prefix.
static double Combinations(int x, int y) =>
Factorial(x) / Factorial(y) / Factorial(x - y);
private static double Chances(int a, int t, int c) =>
Combinations(t, t - c + 1) *
Combinations(a - t, c - 1) /
Combinations(a, t);
You can fiddle the solution
I wrote this:
public static decimal Average(int a, int b)
{
return (a + b) / 2;
}
public static void Main(string[] args)
{
Console.WriteLine(Average(2, 1));
Console.ReadKey();
}
but it returns 1 . But it should return 1.5
How can I fix it to return 1.5 ?
Missing typecasting on the Average function
public static decimal Average(int a, int b)
{
return (decimal)(a + b) / 2;
}
public static void Main(string[] args)
{
Console.WriteLine(Average(2, 1));
}
It returns 1 as integers do not have decimal points and hence the answer is truncated. Eg if the result was 1.99 the result would be 1, eg floor(result).
If you require decimal points you need to use floats or cast your integers to floats. If you require higher precision a double precision floating point could be used (double).
Something else to consider is there are libraries that will do this for you. Eg List.Average() which will average multiple variables.
edit: See this question for a more detailed answer that is specific to division
What is the behavior of integer division?
Solutions upper are wrong. You must check next test cases when work with types:
TEST CASE
0 100
20 -21
21 20
2147483647 2147483647
-2147483647 2147483647
-2147483647 -2147483647
#include <stdio.h>
#include <limits.h>
int average(int a, int b) {
if ( a < 0 && b < 0 ) {
b -= a;
b /= 2;
b += a;
} else if ( a < 0 ) {
b += a;
b /= 2;
} else if ( b < 0 ) {
b += a;
b /= 2;
} else if ( a > b ) {
a -= b;
a /= 2;
a += b;
} else {
b -= a;
b /= 2;
b += a;
}
return b;
}
int main(){
int a = INT_MAX;
int b = INT_MAX;
scanf("%d %d", &a, &b);
printf("Max INTEGER: %d\n", INT_MAX);
printf("Avarage INTEGER: %d\n", average(a, b));
return 0;
}
I'm trying to implement Runge-Kutta for example problems
dy/dt = y - t^2 + 1 and dy/dt = t * y + t^3 in C# and I cannot seem to get the output I'm expecting. I have split my program into several classes to try and look at the work individually. I think that my main error is coming from trying to pass a method through the Runge-Kutta process as a variable using a delegate.
Equation Class:
namespace RK4
{
public class Eqn
{
double t;
double y;
double dt;
double b;
public Eqn(double t, double y, double dt, double b)
{
this.t = t;
this.y = y;
this.dt = dt;
this.b = b;
}
public void Run1()
{
double temp;
int step = 1;
RK4 n = new RK4();
while (t < b)
{
temp = n.Runge(t, y, dt, FN1);
y = temp;
Console.WriteLine("At step number {0}, t: {1}, y: {2}", step, t, y);
t = t + dt;
step++;
}
}
public void Run2()
{
int step = 1;
RK4 m = new RK4();
while (t < b)
{
y = m.Runge(t, y, dt, FN2);
Console.WriteLine("At step number {0}, t: {1}, y: {2}", step, t, y);
t = t + dt;
step++;
}
}
public static double FN1(double t, double y)
{
double x = y - Math.Pow(t, 2) + 1;
return x;
}
public static double FN2(double t, double y)
{
double x = t * y + Math.Pow(t, 3);
return x;
}
}
}
Then Runge-Kutta 4 Class:
namespace RK4
{
class RK4
{
public delegate double Calc(double t, double y);
public double Runge(double t, double y, double dt, Calc yp)
{
double k1 = dt * yp(t, y);
double k2 = dt * yp(t + 0.5 * dt, y + k1 * 0.5 * dt);
double k3 = dt * yp(t + 0.5 * dt, y + k2 * 0.5 * dt);
double k4 = dt * yp(t + dt, y + k3 * dt);
return (y + (1 / 6) * (k1 + 2 * k2 + 2 * k3 + k4));
}
}
}
And my Program Class:
namespace RK4
{
class Program
{
static void Main(string[] args)
{
RunProgram();
}
public static void RunProgram()
{
Console.WriteLine("*******************************************************************************");
Console.WriteLine("************************** Fourth Order Runge-Kutta ***************************");
Console.WriteLine("*******************************************************************************");
Console.WriteLine("\nWould you like to implement the fourth-order Runge-Kutta on:");
string Fn1 = "y' = y - t^2 + 1";
string Fn2 = "y' = t * y + t^3";
Console.WriteLine("1) {0}", Fn1);
Console.WriteLine("2) {0}", Fn2);
Console.WriteLine("Please enter 1 or 2");
switch (Int32.Parse(Console.ReadLine()))
{
case 1:
Console.WriteLine("\nPlease enter beginning of the interval (a):");
double a = Double.Parse(Console.ReadLine());
Console.WriteLine("Please enter end of the interval (b):");
double b = Double.Parse(Console.ReadLine());
Console.WriteLine("Please enter the step size (h) to be used:");
double h = Double.Parse(Console.ReadLine());
Console.WriteLine("Please enter the inital conditions to satisfy y({0}) = d",a);
Console.WriteLine("d = ");
double d = Double.Parse(Console.ReadLine());
Console.Clear();
Console.WriteLine("Using the interval [{0},{1}] and step size of {2} and the inital condition of y({3}) = {4}:", a, b, h, a, d);
Console.WriteLine("With equation: {0}", Fn1);
Eqn One = new Eqn(a, d, h, b);
One.Run1();
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
Environment.Exit(1);
break;
case 2:
Console.WriteLine("\nPlease enter beginning of the interval (a):");
a = Double.Parse(Console.ReadLine());
Console.WriteLine("Please enter end of the interval (b):");
b = Double.Parse(Console.ReadLine());
Console.WriteLine("Please enter the step size (h) to be used:");
h = Double.Parse(Console.ReadLine());
Console.WriteLine("Please enter the inital conditions to satisfy y({0}) = d",a);
Console.WriteLine("d = ");
d = Double.Parse(Console.ReadLine());
Console.Clear();
Console.WriteLine("Using the interval [{0},{1}] and step size of {2} and the inital condition of y({3}) = {4}:", a, b, h, a, d);
Console.WriteLine("With equation: {0}", Fn1);
Eqn Two = new Eqn(a, d, h, b);
Two.Run2();
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
Environment.Exit(1);
break;
default:
Console.WriteLine("Improper input, please press enter to exit.");
Console.ReadLine();
Environment.Exit(1);
break;
}
}
}
}
This is not elegant programming by any means but I don't have the working knowledge to know what I'm doing wrong at this point. From what I was reading I thought that the delegate within the RK4 class would be able to pass through my hard coded diff eq.
You are doing a classical error in the RK4 implementation: Having two variants to position the multiplication with dt to choose from, you are using both.
It is either
k2 = dt*f(t+0.5*dt, y+0.5*k1)
or
k2 = f(t+0.5*dt, y+0.5*dt*k1)
and analogously in the other lines of the algorithm.
I am trying to make a program that calculates the answer of a quadratic equation with the general formula but i am encountering a few errors.
The way I have my Windows Form Application set up it asks for a, b, and c, and substitutes them in the general formula.
I have 3 text boxes, one for each value of a, b and c and one more for the answer, and it is supposed to work with a button I called "calculate".
My problem is that when I try something other than a perfect trinomial square, the answer comes up as NaN.
Here is some of the code I have:
private void textBox1_TextChanged(object sender, EventArgs e)
{
a = Double.Parse(textBox1.Text);
}
^ This is how I am assigning values to the variables
double sqrtpart = b * b - 4 * a * c;
answer = (b + Math.Sqrt(sqrtpart)) / 2 * a;
textBox4.Text = answer.ToString();
group 2a and make sure values are valid (b^2 > 4ac)
answer = (b + Math.Sqrt(sqrtpart)) / (2 * a);
First, make sure that 4ac < b². The quadratic formula also utilizes the ± sign, so we must make two separate variables to hold the two different answers.
double sqrtpart = (b * b) - (4 * a * c);
answer1 = ((-1)*b + Math.Sqrt(sqrtpart)) / (2 * a);
answer2 = ((-1)*b - Math.Sqrt(sqrtpart)) / (2 * a);
textBox4.Text = answer1.ToString() + " and " + answer2.ToString();
If you want your calculator to be able to compute complex numbers try the following
string ans = "";
double root1 = 0;
double root2 = 0;
double b = 0;
double a = 0;
double c = 0;
double identifier = 0;
a =Convert.ToDouble(Console.ReadLine());
b = Convert.ToDouble(Console.ReadLine());
c = Convert.ToDouble(Console.ReadLine());
identifier = b * b - (4 * a * c);
if (identifier > 0)
{
root1 = (-b+(Math.Sqrt(identifier)/(2*a)));
root2 = (-b - (Math.Sqrt(identifier) / (2 * a)));
string r1 = Convert.ToString(root1);
string r2 = Convert.ToString(root2);
ans = "Root1 =" + r1 + "Root2 = " + r2;
Console.WriteLine(ans);
}
if (identifier < 0)
{
double Real = (-b / (2 * a));
double Complex = ((Math.Sqrt((identifier*(-1.00))) / (2 * a)));
string SReal = Convert.ToString(Real);
string SComplex = Convert.ToString(Complex);
ans = "Roots = " + SReal + "+/-" + SComplex + "i";
Console.WriteLine(ans);
}
if (identifier == 0)
{
root1 = (-b / (2 * a));
string Root = Convert.ToString(root1);
ans = "Repeated roots : " + Root;
}
Use the following code:
using System;
using System.Collections.Generic;
using System.Text;
namespace SoftwareAndFinance
{
class Math
{
// quadratic equation is a second order of polynomial equation in a single variable
// x = [ -b +/- sqrt(b^2 - 4ac) ] / 2a
public static void SolveQuadratic(double a, double b, double c)
{
double sqrtpart = b * b - 4 * a * c;
double x, x1, x2, img;
if (sqrtpart > 0)
{
x1 = (-b + System.Math.Sqrt(sqrtpart)) / (2 * a);
x2 = (-b - System.Math.Sqrt(sqrtpart)) / (2 * a);
Console.WriteLine("Two Real Solutions: {0,8:f4} or {1,8:f4}", x1, x2);
}
else if (sqrtpart < 0)
{
sqrtpart = -sqrtpart;
x = -b / (2 * a);
img = System.Math.Sqrt(sqrtpart) / (2 * a);
Console.WriteLine("Two Imaginary Solutions: {0,8:f4} + {1,8:f4} i or {2,8:f4} + {3,8:f4} i", x, img, x, img);
}
else
{
x = (-b + System.Math.Sqrt(sqrtpart)) / (2 * a);
Console.WriteLine("One Real Solution: {0,8:f4}", x);
}
}
static void Main(string[] args)
{
// 6x^2 + 11x - 35 = 0
SolveQuadratic(6, 11, -35);
// 5x^2 + 6x + 1 = 0
SolveQuadratic(5, 6, 1);
// 2x^2 + 4x + 2 = 0
SolveQuadratic(2, 4, 2);
// 5x^2 + 2x + 1 = 0
SolveQuadratic(5, 2, 1);
}
}
}
Here is the original source.
A little late, but here is my solution:
using System;
using System.Collections.Generic;
namespace MyFunctions
{
class Program
{
static void Main(string[] args)
{
printABCSolution(1, -3, 4);
printABCSolution(1, -4, 4);
printABCSolution(1, -5, 4);
printABCSolution(9, 30, 25);
printABCSolution(9, -15, 25);
Console.ReadKey();
}
private static void printABCSolution(double a, double b, double c)
{
Console.WriteLine($"Solution a={a} b={b} c={c}");
var solution = ABCMath.ABCFormula(a, b, c);
Console.WriteLine($"# Solutions found: {solution.Count}");
solution.ForEach(x => Console.WriteLine($"x={x}"));
}
}
public static class ABCMath
{
public static List<double> ABCFormula(double a, double b, double c)
{
// Local formula
double formula(int plusOrMinus, double d) => (-b + (plusOrMinus * Math.Sqrt(d))) / (2 * a);
double discriminant = b * b - 4 * a * c;
List<double> result = new List<double>();
if (discriminant >= 0)
{
result.Add(formula(1, discriminant));
if (discriminant > 0)
result.Add(formula(-1, discriminant));
}
return result;
}
}
}
Output:
Solution a=1 b=-3 c=4
# Solutions found: 0
Solution a=1 b=-4 c=4
# Solutions found: 1
x=2
Solution a=1 b=-5 c=4
# Solutions found: 2
x=4
x=1
Solution a=9 b=30 c=25
# Solutions found: 1
x=-1,66666666666667
Solution a=9 b=-15 c=25
# Solutions found: 0
Here is code:
using System;
namespace RoomPaintCost
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("This program applies quadratic formula to Ax^2+Bx+C=0 problems");
double[] ABC= getABC();
double[] answerArray=QuadFormula(ABC);
Console.WriteLine("Positive answer: {0:0.000} \n Negative answer: {1:0.000}", answerArray[0], answerArray[1]);
}
//Form of Ax^2 + Bx + C
//Takes array of double containing A,B,C
//Returns array of positive and negative result
public static double[] QuadFormula(double[] abc)
{
NotFiniteNumberException e = new NotFiniteNumberException();
try
{
double a = abc[0];
double b = abc[1];
double c = abc[2];
double discriminant = ((b * b) - (4 * a * c));
if (discriminant < 0.00)
{
throw e;
}
discriminant = (Math.Sqrt(discriminant));
Console.WriteLine("discriminant: {0}",discriminant);
double posAnswer = ((-b + discriminant) / (2 * a));
double negAnswer = ((-b - discriminant) / (2 * a));
double[] xArray= { posAnswer,negAnswer};
return xArray;
}
catch (NotFiniteNumberException)
{
Console.WriteLine("Both answers will be imaginary numbers");
double[] xArray = { Math.Sqrt(-1), Math.Sqrt(-1) };
return xArray;
}
}
public static double[] getABC()
{
Console.Write("A=");
string sA = Console.ReadLine();
Console.Write("B=");
string sB = Console.ReadLine();
Console.Write("C=");
string sC = Console.ReadLine();
int intA = Int32.Parse(sA);
int intB = Int32.Parse(sB);
int intC = Int32.Parse(sC);
double[] ABC = { intA, intB, intC };
return ABC;
}
}
}