I am pretty new to C# and I'm stuck with a problem in the code. Apparently, there is a casting error, can you tell me what is it?
Here's the code
public static void Main(string[] args)
{
// side a and b
Console.WriteLine("Side A of 90° triangle");
double a = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Side B");
double b = Convert.ToDouble(Console.ReadLine());
// c^2
int csqr = (a * a) + (b * b);
int hypo = Math.Sqrt(csqr);
// hypo
Console.WriteLine("hypotenuse:- " + hypo);
}
The variables csqr and hypo should be of type double while you defined them as int.
Sqrt is a method to find the square root. thus it takes a parameter of type double and returns double.
sqrt documentation
csqr variable should be of type double because of the arithmetic operations on a double operands.
You cannot put a double into an int. Variables hypo csqr must be double.
public static void Main(string[] args)
{
//side a and b
Console.WriteLine("Side A of 90° triangle");
double a = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Side B");
double b = Convert.ToDouble(Console.ReadLine());
//c^2
double csqr = (a * a) + (b * b);
double hypo = Math.Sqrt(csqr);
//hypo
Console.WriteLine("hypotenuse:- " + hypo);
}
Related
I am trying to solve this question :
Create a function of type Generic so that it receives 5 marks, regardless of the type of these marks. Calculate the average, calculate the marks above and below the average, and print the result on the screen.
but I did not know how! , I do this but I don't know how to display the marks above and below the average.
and I am not sure if I solve the question in the right way.
using System;
namespace oopGeneric
{
class Calculator
{
public int high = 0, low = 0;
public double Sum<A, B, C, D, E>(int n1, double n2, double n3, int n4, int n5)
{
double sum = n1 + n2 + n3 + n4 + n5;
Console.WriteLine("The Summation {0} ", sum);
double avg = sum / 5;
return avg;
}
class Program
{
static void Main(string[] args)
{
Calculator calc = new Calculator();
double sum = calc.Sum<int, double, double, int, int>(5, 5.5, 15.0, 6, 8);
// Console.WriteLine("above" + high);
Console.WriteLine(sum);
}
}
}
}
In the method Sum, you can insert the code
double avg = sum / 5;
var marks = new double[]{n1,n2,n3,n4,n5};
foreach (double m in marks)
if (m > avg) Console.WriteLine(m);
You will get the marks above the average.
This is the solution using matching pattern.
public double Sum<A, B, C, D, E>(A n1, B n2, C n3, D n4, E n5)
{
double sum = 0;
sum+= (n1 is Int32 n1_as_integer) ? n1_as_integer :
(n1 is Double n1_as_double) ? n1_as_double : 0;
sum+= (n2 is Int32 n2_as_integer) ? n2_as_integer :
(n2 is Double n2_as_double) ? n2_as_double : 0;
return sum / 5;
}
This is the solution using params + matching pattern.
public double Sum(params object[] N)
{
double sum = 0;
foreach(var i in N)
sum+= (i is Int32 i_as_integer) ? i_as_integer :
(i is Double i_as_double) ? i_as_double : 0;
return (N.Lenght>0) ? sum / N.Lenght : 0;
}
You may want to consider accepting any IConvertible object as a generic constraint.
IConvertible
An object that implements IConvertible is required to implement public methods that either convert to the designated primitive runtime type(such as int, float) or throw an InvalidCastException.
These types include
bool sbyte byte
u/short u/int u/long
double float decimal Single
DateTime char string
We can use IConvertible as a constraint to allow only objects that can be converted to primitives.
For example we could convert any of the above types(except the ones that aren't numbers they will throw InvalidCastException) to a double with this method.
double Convert<T>(T Value) where T : IConvertible
{
return Value.ToDouble(null);
}
// These all work
Convert(10m); // (decimal)
Convert(10); // (int)
Convert(10f); // (float)
Convert((sbyte)10);
Convert((long)10);
Using this we can construct an average function that can accept an atrocity such as this:
Average<IConvertible>(10, 10m, (ushort)10, (byte)10, (sbyte)10, 10f, 10d, (long)10, (ulong)10, (uint)10);
Which if we did everything right should ideally output 10d;
public double Average<T>(params T[] numbers) where T : IConvertible
{
// create a place to put the sum, since we need it to calculate the average later
double sum = default;
// store the length of the array since we use it in multiple places
int count = numbers.Length;
for (int i = 0; i < count; i++)
{
// convert value to double, all primitive IConvertible types are required to cast to double(generally)
double value = numbers[i].ToDouble(null);
// add value to the sum so we can calculate the average later
sum += value;
}
// return the average score
return sum / (double)count; // cast int to double to avoid unintentional integer math
}
Editors Note
The above example assumes the requirement to use Generics. You can simplify the un-intuitive call for Average<IConvertible> for mixed-types with a solution such as Average(params IConverible[] numbers), however that would not be using generics.
Our teacher asked us to use C# to do a trapezoidal rule solution;
He wants us to break it down into three methods.
Below is the the question and my code so far:
Numerical integration is a technique that is particular suitable for
computer applications. In exercise we will try to implement the
trapezoidal rule. The integral of a mathematical function is the area
between the curve and the x-axis. If the area is divided into little
trapezoids, then the integral is approximated by the area of these
geometrical figures.
You will try to find the area under the curve y = 6x^2-7x+2 in the
region from x = 0.5 to x = 1.5 (N.B. your answer should work out to
about be 1.54, however the actual answer is 1.5). The area is given by
the formula
where y0 and y1 are the height of the vertical lines i.e. the value of
the function.
This problem can be decomposed into three parts as follows:
Write a method called EvaluateQuadraticValue(double x, double a, double b, double c) that takes four double arguments: the value of x,
the coefficient of the x2 term, the coefficient of the x and the
constant. The method will compute and return the result value of y
given by the expression y = ax2+ba+c.
Write a method called ComputeQuadraticValues(double startX, double increments, int numberOfIntervals, double a, double b, double c) that
takes six arguments: the start value of x, the increments and the
number of intervals and the coefficients of the quadratic equation.
This method will figure out the values of x0, x1, x2 etc. by invoking
the previous question. The results of the methods calls are collected
and returned as a double array.
Write a method called ApplyTrapeziodalRule(double startX, double endX, int numberOfIntervals, double a, double b, double c) . The
arguments are described in the previous question. This method calls
the previous method and process the double array that is returned to
compute the area under the curve by applying the formula
And my code so far:
public static double EvaluateQuadraticValue(double x, double a, double b, double c)
{
double y = a * Math.Pow(x, 2) + b * x + c;
Console.WriteLine("The y coordinate for this x is: {0}", y);
return y;
}
public static double[] ComputeQuadraticValues(double startX, double increments, int numberOfIntervals, double a, double b, double c)
{
double[] xPoints = new double[numberOfIntervals];
for (int index = 0; index < numberOfIntervals; index++)
{
xPoints[index] = startX;
Console.WriteLine("X{0} is {1}: ",index, xPoints[index]);
EvaluateQuadraticValue(startX, a, b, c);
startX = startX + increments;
}
return xPoints;
}
public static void ApplyTrapeziodalRule(double startX, double endX, int numberOfIntervals, double a, double b, double c)
{
double increments = Convert.ToInt32(Console.ReadLine());
double[] xPoints = ComputeQuadraticValues(startX, increments, numberOfIntervals, a, b, c);
//double[] values = a * Math.Pow(xPoints[i], 2) + b * xPoints[i] + c;
//double y = xPoints.Sum();
/*for (int i = 0; i < numberOfIntervals; i++)
{
}*/
//Console.WriteLine(y + " sum");
}
Currently I'm having trouble with the third method.
Since my double array from ComputeQuadraticValues() are x0, x1, x2 etc. How do I use this array to get (y0 + 2*y1 + 2*y2 + ...... + 2*yn + y(n+1))?
Any hints or tips are appreciated!
I agree with #MartinLiversage and also think there are some other tricky parts in the excersise. I'll try to do my best giving you a good answer. Let me know how this works for you.
This is the curve represented by 6x^2-7x+2 and you're required to compute the area in blue:
What you're doing is a numerical method, and the logic behind is that if you manage to split the area in an infinite number of points, you'll get the total area more accurately. The more points you add, more accurate the result will be.
The thing is that in Computer Sciences, infinity is not possible, because resources are limited and eventually you'll need to set a limit.
I've set 10 as number of interval (N) so you'll get 11 points and the sample is readable.
Now, your first method is just the helper in order to evaluate a function in the form ax^2 + bx + c.
public static double EvaluateQuadraticValue(double x, double a, double b, double c)
{
double y = a*Math.Pow(x,2) + b*x + c;
return y;
}
The second is where I think the problem is. I'd implement it like this:
public static double[] ComputeQuadraticValues(double startX, double increments, int numberOfIntervals, double a, double b, double c)
{
//We need numberOfInterval + 1 values
double[] yPoints = new double[numberOfIntervals+1];
for (int index = 0; index <= numberOfIntervals; index++, startX += increments)
{
//evaluate the function and get the y value for this x
yPoints[index] = EvaluateQuadraticValue(startX, a, b, c);
//Console.WriteLine("({0}, {1})", startX, yPoints[index]);
}
return yPoints;
}
And the last is the one who gets called by your Main() function:
public static void ApplyTrapezoidalRule(double startX, double endX, int numberOfIntervals, double a, double b, double c)
{
double increments = (endX - startX)/numberOfIntervals;
Console.WriteLine("increment: " + increments);
//compute the function value for each X (generated from startX + increment).
double[] yPoints = ComputeQuadraticValues(startX, increments, numberOfIntervals, a, b, c);
var first = (double)(endX - startX)/(2*numberOfIntervals);
Console.WriteLine("({0} - {1})/2*{2} = {3}", endX, startX, numberOfIntervals, first);
var sum = yPoints[0];
for (int i = 1; i <= numberOfIntervals; i++)
sum += 2 * yPoints[i];
sum += yPoints[numberOfIntervals];
var result = first * sum;
Console.WriteLine("result: " + result);
}
I've declared more variables so you'll see the process and the code is again more readable.
You can see this fiddle and play with the numberOfIntervals you pass in. Note that the value will be more accurate if you increase the number of intervals.
Hope this helps!
To me the description of ComputeQuadraticValues is confusing. It would make sense if it returned y0, y1, y2 etc. and not x0, x1, x2 etc. as stated.
Looking at your code for ComputeQuadraticValues you call EvaluateQuadraticValue (which computes y given x). However, the computed y value is not stored anywhere. You can rename xPoints to yPoints and then store the computed y value in that array before returning it as the result of the function.
With that change you should then be able to write a working version of ApplyTrapeziodalRule.
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'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);
}
}