This code below grabs 3 inputs from the console and then parses the numbers, after it then gets sent to getRealRoots method. which finds whether it has 2, 1 or no roots. The out parameters in the getrealroots are showing the following error:
The out parameter 'r1' must be assigned to before control leaves the
current method
The out parameter 'r2' must be assigned to before control leaves the current method
using System;
namespace Quadratic
{
public class Program
{
static public void Main(string[] args)
{
Console.WriteLine("Enter three numbers, (A,B,C)");
Double? a = GetDouble();
Double? b = GetDouble();
Double? c = GetDouble();
getRealRoots(a, b, c,out r1,out r2);
//throw new NotImplementedException("implement main");
}
static public int getRealRoots(double A, double B, double C, out double? r1, out double? r2)
{
double discriminant = B * B - 4 * A * C;
if (discriminant > 0)
{
r1 = (-B + Math.Sqrt(discriminant)) / (2 * A);
r2 = (-B - Math.Sqrt(discriminant)) / (2 * A);
Console.WriteLine("The equation " + GetQuadraticString(A, B, C) + " has two real roots:" + r1 + " " + r2);
}
else if (discriminant == 0)
{
r1 = -B / (2 * A);
Console.WriteLine("The equation " + GetQuadraticString(A, B, C) + " has one real root:" + r1);
}
else
{
Console.WriteLine("The equation " + GetQuadraticString(A, B, C) + " has no real roots:");
}
}
//throw new NotImplementedException("write a method that uses out variables to return the real discriminants of a quadratic");
}
}
First, you have the return type int, but do not return an int.
Second, the error message says that you have to assign your out parameters some value no matter what path of execution your method takes. You could solve this by assigning them some "default" values at the beginning of the method. Maybe like this?:
r1 = default (double);
r2 = null;
Hope I could help
As per the documentation on the out parameter modifier:
Variables passed as out arguments do not have to be initialized before being passed in a method call. However, the called method is required to assign a value before the method returns.
In the case of your provided code, in the method getRealRoots, you are:
Setting the out value of r1 and r2 where discriminant > 0
Setting the out value of r1 where discriminant == 0, but not the value of r2
Not setting r1, or r2 where none of the above conditions are met.
As the called method is required to assign a value, you must set the value of r1 and r2 in each execution pathway.
As you have defined the values as a nullable type, you can begin your method with some default values to resolve your issue:
static public int getRealRoots(double A, double B, double C, out double? r1, out double? r2)
{
r1 = null;
r2 = null;
// ... your method code
}
The default values are then overwritten under the specific IF conditions you have set.
Related
I have made bisection method program in C# Console Application. Bisection method works, but for function which is already written in the code. I want to edit program that user can input function which they want to use for bisection method. For example Console.ReadLine() for input "x^2 + x - 2" and then I want it automatically written after return in the code below.
static double Function(double x)
{
return x*x - 2;
} //this is Function which I used in code.
Here is the whole code. (as i mentioned it works for function which is written in static double Function(double x) part
using System;
namespace MPI
{
class MainClass
{
public static void Main(string[] args)
{
// in [a,b]
double inPoc = 0; //a
double inKraj = 0; //b
double sredina = 0;
double tacnost = 0;
Start:
int i = 0; //brojac
Console.Write("Unesite početak intervala: ");
inPoc = Convert.ToDouble(Console.ReadLine());
Console.Write("Unesite kraj intervala: ");
inKraj = Convert.ToDouble(Console.ReadLine());
Console.Write("Unesite tacnost: ");
tacnost = Convert.ToDouble(Console.ReadLine());
sredina = (inPoc + inKraj) / 2;
if (Function(inPoc) * Function(inKraj) < 0)
{
while ((Math.Abs(inPoc - inKraj)) > tacnost)
{
sredina = (inPoc + inKraj) / 2;
Console.WriteLine("trenutno X: " + sredina);
Console.WriteLine("Funkcija za trenutno x ima vrednost: " + Function(sredina));
Console.WriteLine("");
i++;
if (Function(sredina) < 0)
{
inPoc = sredina;
}
else
{
inKraj = sredina;
}
}
Console.WriteLine("X: " + sredina);
Console.WriteLine("Broj izvrsenih koraka je " + i);
}
else
{
Console.WriteLine("Krajevi intervala funkcije su istog znaka");
Console.WriteLine();
}
goto Start; //sluzi da vrati program na pocetak kako bi ga opet koristili
}
static double Function(double x)
{
return x*x - 2; //primer funkcije
}
}
}
Looks like this question is asking about the same.
There are two solutions to do this:
Solution 1 - just use Flee.
Copy-paste from documentation:
ExpressionContext context = new ExpressionContext();
VariableCollection variables = context.Variables;
variables.Add("a", 100);
variables.Add("b", 1);
variables.Add("c", 24);
IGenericExpression<bool> e = context.CompileGeneric<bool>("(a = 100 OR b > 0) AND c <> 2");
bool result = e.Evaluate();
So you can do the same, just change input/output types and put your input line into the CompileGeneric
Solution 2 - parse input string manually.
So question can be divided to the two parts:
How to parse input string into the expression tree.
How to execute this tree.
For the first item - please check reverse polish notation. It allows to construct computation stack.
Next you will able to compute your expression tree. Each operand (after trimming) will have variable or integer constant. So just replace variable to the actual value and just parse string to the integer.
This question already has answers here:
What does "Use of unassigned local variable" mean? [duplicate]
(11 answers)
Closed 4 years ago.
This is a program I wrote to solve quadratic equations. I have three textboxes for inputting the value of a,b and c. If I use the following code, without assigning any value to a,b or c before the if statement, I get an error "Use of unassigned variable" in the line double Delta = Math.Pow(b, 2) - 4 * a * c;, only regarding variable b and c(not a).
private void bt_Calculate_MouseClick(object sender, MouseEventArgs e)
{
Double a, b, c;
if (txt_b.Text != "" && txt_b.Text != "" && txt_c.Text != ""
&& (Double.TryParse(txt_a.Text, out a) && Double.TryParse(txt_b.Text, out b) && Double.TryParse(txt_c.Text, out c)) == true)
{
double Delta = Math.Pow(b, 2) - 4 * a * c;
if (Delta > 0)
{
Double x1 = Math.Round((-b + Math.Sqrt(Delta)) / (2 * a), 4);
Double x2 = Math.Round((-b - Math.Sqrt(Delta)) / (2 * a), 4);
txt_Result1.Text = Convert.ToString(x1);
txt_Result2.Text = Convert.ToString(x2);
}
else if (Delta == 0)
{
Double x1 = Math.Round(-b / (2 * a), 4);
txt_Result1.Text = Convert.ToString(x1);
}
else
{
MessageBox.Show("Impossible Equation.");
}
}
else if ((txt_a.Text == "") || (txt_b.Text == "") || (txt_c.Text == ""))
{
MessageBox.Show("Provide a value for a, b and c.");
}
else
{
MessageBox.Show("Provide a valid number, please");
}
}
However, the program doesn't give any error and outputs the right result when I assign the value 0 to all three variables before the if statement.
As such: Double a=0, b=0, c=0;
I would like to know why this happens exactly. Isn't TryParse supposed to store the value in the given variable if it returns true? My program also works if I assign the textboxes content to their respective variable in the beginning of the first if block. For example: txt_a.Text = a.
The compiler just isn't smart enough.
Something like this is totally OK:
double a, b;
if (double.TryParse("5", out a) && double.TryParse("6", out b))
// works fine
Console.WriteLine("a = {0}, b = {1}", a, b);
But if we make the conditional statement a little more complex, then suddenly the compiler is no longer sure whether you've initialized the variable or not:
double a, b;
if (true == (double.TryParse("5", out a) && double.TryParse("6", out b)))
// generates an error
Console.WriteLine("a = {0}, b = {1}", a, b);
It's perfectly fine to initialize those variables to 0.
I am trying to make a simple calculator with arrays in C#. Firstly I tried making it using two integers and one operator only and it worked well. Now I am trying to do so that the user can make the expression as long as they like. For example 7 * 7 + 1 / 50 instead of a simple 9 + 8 which includes only one operator and two integers. The problem is that whenever I type a long expression with multiple numbers and operators it only calculates the first 2 numbers with the first operator. What is a good fix for this problem ? Thanks in advance.
static void Main()
{
while (true)
{
Console.WriteLine("Write an expression with two numbers and an operator with space in-between, for example, 4 + 2");
string expression;
string[] array;
string[] array1;
expression = Console.ReadLine();
array = expression.Split();
array1 = Calculation(array);
Console.WriteLine("Press ENTER to write a new expression.");
Console.ReadLine();
Console.Clear();
}
}
static string[] Calculation(string[] arr)
{
double numLeft= 0.0;
double numRight = 0.0;
string sign = "";
double result = 0.0;
int index = 1;
while (true)
{
numLeft = Convert.ToDouble(arr[0]);
sign = Convert.ToString(arr[index]);
numRight = Convert.ToDouble(arr[index + 1]);
index = index + 2;
if (sign == "+")
{
Console.Clear();
Console.WriteLine();
result= result + numLeft;
}
else if (sign == "-")
{
Console.Clear();
result = result + numLeft;
numLeft = 0 - numRight;
}
else if (sign == "*")
{
Console.Clear();
numLeft = numLeft * numRight;
}
else if (sign == "/")
{
Console.Clear();
numLeft = numLeft / numRight;
}
else
{
break;
}
result = result + numLeft;
Console.WriteLine("Answer: {0}", result);
return arr;
}
return arr;
}
because you return the array at the end of the "while true", so only first 2 get calculated.
Also, this will not be correct. for example: 2 + 3 * 4 = 14, and not 20, like your calculator will calculate.
How about this?
Split your operation string into pieces and fill a list with them;
7 * 7 + 1 / 50 => [7][*][7][+][1][/][50]
Then go through the list and solve the * and / operations. When you encounter one of the operators remove the operator element, the one before it and the one after it, and replace them with the result. Keep in mind that the list length changes.
first iteration => [49][+][1][/][50]
second iteration => [49][+][0.02]
Then do the same for + and - operators
first iteration => [49.02]
When you have only one element remaining in the list, that is your result.
For simple computations there exists a method in .net:
public static int Compute(string operation)
{
return new DataTable().Compute("7 * 7 + 1 / 50", null);
}
Source: C# Math calculator
If you really want to implement this I would suggest a recursive binary tree algorithm.
Pseudo-code:
1. Split incoming string on places where there is a mathematical operation symbol and turn in to a binary tree
2. Go through this tree and resolve operations that have a greater priority (* comes before +)
3. Recursion should return value of two child leafs and so on until it yields only one value to the main program
using System;
namespace _2nd_A_recap
{
class Program
{
static void Main(string[] args)
{
int result;
int a = 20, b = 10;
result = (a + b );
Console.WriteLine("Addition Opertaor:" + result);
result = (a - b);
Console.WriteLine("Subtraction Operator:" + result);
result = (a * b);
Console.WriteLine("Multiplication Operator:" + result);
result = (a / b);
Console.WriteLine("Division Operator:" + result);
result = (a % b);
Console.WriteLine("Modulus Operator:" + result);
Console.WriteLine("Press enter to end Calculator...");
Console.ReadKey();
}
}
}
public static void AddCharToNum <I> (ref I OriginalNumber, char NumberToAdd_Char) where I : struct {
double NumberToAdd = char.GetNumericValue (NumberToAdd_Char);
OriginalNumber = OriginalNumber * 10 + (int) NumberToAdd;
}
It displays this error: Operator *' cannot be applied to operands of typeI' and `int'
EDIT: The problem I'm trying to solve is this:
I don't want to repeat this code again and again:
switch (ParseState) {
case 1:
{
a = (a * 10) + char.GetNumericValue (NumberToAdd_Char);
}
case 2:
{
x = (x * 10) + char.GetNumericValue (NumberToAdd_Char); //where x is a float
}
case 3:
{
b = (b * 10) + char.GetNumericValue (NumberToAdd_Char); //where b is a double
}
case 4:
{
c = (c * 10) + char.GetNumericValue (NumberToAdd_Char); //where c is an integer
}
}
Since you are adding float number to the result anyway you might as well just use float or double variables. Also, it seems that your method logically returns number with additional character while having void return type. I would rewrite your method as follows:
public static double AddCharToNum (double originalNumber, char charToAdd) {
double numberToAdd = char.GetNumericValue(charToAdd);
return originalNumber * 10 + numberToAdd;
}
It seems to me that you are trying to parse some string of digits into integer digit by digit, I'm right?
If that is the case simply use int.Parse or int.TryParse
Enjoy
I guess you are using custom classes, which provice a numeric value. If so, you should make use of operator overloading.
C# allows user-defined types to overload operators by defining static member functions using the operator keyword
Check this page for more informations: MSDN: Overloadable Operators (C# Programming Guide)
Here is a quick example:
public static I operator *(I first, int second)
{
/* Pseudo code:
var number = first.Value;
I outVal = new I();
outVal.Value = number * second;
return outVal;
*/
}
Edit:
When using these operators on different/generic types like "I" is. Make a variable dynamic before using operators.
Like this:
dynamic dynOriginalNumber = OriginalNumber;
OriginalNumber = (OriginalNumber)(dynOriginalNumber * 10 + (float) NumberToAdd);
Hello guys I am a newbie and I am currently a first year in Computer Science. We have been given an exercise in which we have to convert from Fahrenheit to Celcius with methods (professor advised no static). We have started with C#. Here is my code.
namespace Week3_Exe3._1{
public class Formula
{
public double F;
public double C;
public void calculate(double F, double C)
{
C = (5 / 9) * (F - 32);
}
public static void Main(string[] args)
{
Console.WriteLine("Please enter the Fahrenheit you wish to convert");
F = double.Parse(Console.ReadLine());
Formula form = new Formula();
Console.WriteLine(F + "Fahrenheit correspond to " + form.calculate() + "Degrees celcius");
}
}
}
I am currently working with Visual Studio Community 2015 and in form.calculate, it reds out the calculate with the error
CS7036 C# There is no argument given that corresponds to the required
formal parameter '' of 'Formula.calculate(double, double)'
I searched for it but I still do not understand what is missing. I created an instance to use, but it's not working. Can anyone give me answer?
Your calculate method expect 2 parameters but you try to call it without parameters. In my humble opinion, it shouldn't take two parameters at all. Just one fahrenheit parameter is enough so it can calculate celsius value.
Also 5 / 9 performs an integer division —it always discards the fractional part— so it will always return 0.
A static method should be enough for your case;
static double Celsius(double f)
{
return 5.0/9.0 * (f - 32);
}
There a few errors in your code. First of all, your function only requires one input parameter, the temperature in Fahrenheit. After you have resolved this, you will find temperature of 100 Fahrenheit will return a temperature of 0 Celcius and this is obviously not correct. You need to modify your equation to use at least one fractional part otherwise C# will implicitly cast the values to integers.
using System;
namespace Week3_Exe3._1
{
public class Formula
{
public double calculate(double F)
{
return (5.0 / 9.0) * (F - 32.0);
}
public static void Main(string[] args)
{
Console.WriteLine("Please enter the Fahrenheit you wish to convert");
var F = double.Parse(Console.ReadLine());
Formula form = new Formula();
Console.WriteLine(F + " Fahrenheit correspond to " + form.calculate(F) + " Degrees celcius");
}
}
}
Your code has a few holes, my suggested rewrite is this:
public class Formula
{
public double F;
public double C;
public void calculate()
{
C = (5.0 / 9.0) * (F - 32);
}
public static void Main(string[] args)
{
Console.WriteLine("Please enter the Fahrenheit you wish to convert");
Formula form = new Formula();
form.F = double.Parse(Console.ReadLine());
form.calculate();
Console.WriteLine(F + "Fahrenheit correspond to " + form.C + "Degrees celcius");
}
}
keep in mind that this code only works for F => C, not the other way around.
The right answer is not going to be much use to you unless you understand what parameters and return values are and how to use them.
In your definition of the calculate method
public void calculate(double F, double C)
the method is expecting two input parameters, F and C. This means when you call the method from your main method, you need to pass in two values between the parentheses:
form.calculate(F, C)
As others have pointed out, you really only need one parameter, for the Farenheight. Which brings us to the next bit - how do you get a value back for C? This is what return values are for. That little word in between public and calculate defines the return type for your method. void means nothing is returned. In your case you'll be wanting to return a double. So putting this together the method definition should look like this
public double calculate(double F)
Finally you must actually return the value at the end of your method:
double C = (5.0 / 9.0) * (F - 32);
return C;
As you already assign the value of C you can remove C parameter from your function defenition code. Than your function must be like.
public void calculate(double F)
{
C = (5.0 / 9.0) * (F - 32.0);
}
Than in your code
public class Formula
{
// public double F; remove because F is used as parameter
public double C;
public void calculate(double F)
{
C = (5.0 / 9.0) * (F - 32.0);
}
public static void Main(string[] args)
{
Console.WriteLine("Please enter the Fahrenheit you wish to convert");
var F = double.Parse(Console.ReadLine()); // Creating new variable
Formula form = new Formula();
form.calculate(F); // Pass parameter to our function
Console.WriteLine(F + "Fahrenheit correspond to " + form.C /* retrive the results of calculation */ + "Degrees celcius");
}
}