why NaN number? - c#

I am trying to calculate the delta of a number using a formula of bhaskara and delta but it is giving NaN in the message box
//Variables declaration
int a = 800, b = 500, c = 350;
double delta, a1, a2;
//Formulas
delta = (b*b) - (4*a*c);
a1 = (-b + Math.Sqrt(delta)) / (2 * a);
a2 = (-b - Math.Sqrt(delta)) / (2 * a);
//Output
MessageBox.Show(a1.ToString());
MessageBox.Show(a2.ToString());

The value of delta is -870000.
That's not a value you can take the square root of (and get a real number anyway).
From the Math.Sqrt docs:

As Broots said Math.sqrt of negative number will return NaN. There is a Complex struct that should do what you need:
Complex c = Complex.Sqrt(-25); // has a value of approximately 0 + 5i

Related

How to show solutions for quadratic formula

So I wrote a Quadratic formula program in C#, how do I take the quadratic formula program and modify it so that the program correctly displays the number of solutions.
if there are two solutions,
(x - x1)(x - x2) = 0
if there is only one solution,
(x - x0)^2 = 0
if there are no solutions,
No Solution.
This is the program, if someone could show the solution to this for me that would be wonderful, I'm really stuck on how to do it.
using System;
namespace quadraticequation
{
class MainClass
{
public static void Main(string[] args)
{
Console.WriteLine("Enter a number for a"); //ask the user for information
double a = double.Parse(Console.ReadLine()); //Gets a from the user
Console.WriteLine("Enter a number for b"); //asks the user for information
double b = double.Parse(Console.ReadLine()); //Gets b from the user
Console.WriteLine("Enter a number for c"); //asks the user for information
double c = double.Parse(Console.ReadLine()); //Gets c from the user
//double.Parse --> is used to convert a number or string to a double.
//Console.ReadLine() --> is used to take the input from the user.
//We call a function here
Quadratic(a, b, c);
}
//We need to create a new function
public static void Quadratic(double a, double b, double c)
{
double deltaRoot = Math.Sqrt(b * b - 4 * a * c); //Math.Sqrt takes the square root of the number
if (deltaRoot >= 0) // we use an if statement here to handle information
{
double x1 = (-b + deltaRoot) / 2 * a; //We write the information for x1 here
double x2 = (-b - deltaRoot) / 2 * a; //We write the information for x2 here
Console.WriteLine("x1 = " + x1 + " x2 = " + x2); //we use this to write the roots
}
else // we use an else statement so that we dont return an error when there are no roots
{
Console.WriteLine("There are no roots");
}
}
}
}
I think you have to review your second degree formula solution-skills. You write:
double deltaRoot = Math.Sqrt(b * b - 4 * a * c);
But the test is actually whether b2-4×a×c is larger than or equal to zero: indeed that is actually why we check it: because we cannot take the square root of a negative number (yeah there exist complex numbers that can take the square root of a negative number, but let's ignore that for now).
So the solution is to write it like:
public static void Quadratic(double a, double b, double c) {
double delta = b*b-4*a*c; //only delta
if (delta > 0) {
double deltaRoot = Math.Sqrt(delta);
double x1 = (-b + deltaRoot) / (2 * a); //We write the information for x1 here
double x2 = (-b - deltaRoot) / (2 * a); //We write the information for x2 here
Console.WriteLine("x1 = " + x1 + " x2 = " + x2); //we use this to write the roots
} else if(delta == 0) {
double x1 = -b/(2*a);
Console.WriteLine("x1 = " + x1); //we use this to write the roots
} else {
Console.WriteLine("There are no roots");
}
}
You also have to write (-b + deltaRoot) / (2*a) (with (2*a)), otherwise you will multiply (-b + deltaRoot) / 2 with a instead.
A final note is that equality comparisons with floating points is very tricky so delta == 0 will often fail since the result can be something 1e-20-ish, which is simply an error when performing floating point arithmetic. So it is perhaps better to use a small range of values.
This gives:
csharp> MainClass.Quadratic(1,1,1);
There are no roots
csharp> MainClass.Quadratic(1,1,0);
x1 = 0 x2 = -1
csharp> MainClass.Quadratic(1,0,0);
x1 = 0

Calculation results in NaN [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I was trying to calculate the result of a second degree equation using C#, but i get the result NaN. Can someone check my code to locate the error ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace desafio2_2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Please insert the values that multiply x², x and the independent term respectively: ");
float a = float.Parse(Console.ReadLine());
float b = float.Parse(Console.ReadLine());
float c = float.Parse(Console.ReadLine());
double bhaskarap1 = (Math.Pow(b, 2)) + (- 4 * a * c);
double raiz1 = (-b + Math.Sqrt(bhaskarap1)) / (2 * a);
double raiz2= (-b - Math.Sqrt(bhaskarap1)) / (2 * a);
Console.WriteLine(raiz1);
Console.WriteLine(raiz2);
}
}
}
It may be possible that the quadratic equation has no real roots. In this case the discriminant will be negative.
Math.Sqrt(x) returns NaN when when x is negative. You should test the discriminant for negative number before you call the square root function.
static void Main(string[] args)
{
Console.WriteLine("Please insert the values that multiply x², x and the independent term respectively: ");
float a = float.Parse(Console.ReadLine());
float b = float.Parse(Console.ReadLine());
float c = float.Parse(Console.ReadLine());
double bhaskarap1 = (Math.Pow(b, 2)) + (- 4 * a * c);
if (bhaskarap1 < 0)
{
Console.WriteLine("There are no real solutions.");
return;
}
double raiz1 = (-b + Math.Sqrt(bhaskarap1)) / (2 * a);
double raiz2= (-b - Math.Sqrt(bhaskarap1)) / (2 * a);
Console.WriteLine(raiz1);
Console.WriteLine(raiz2);
}
argument of sqrt method must be positive.
I would check for NaN using a ternary operator like I did below to handle the case of a negative value for sqrt.
float a = 4.0f, b = 7.0f, c = -3.0f;
double my_var = ((Math.Pow(b, 2)) + (-4 * a * c));
Console.WriteLine(my_var);
Console.WriteLine(((-b + Math.Sqrt(-1 * my_var)) / (2 * a)));
double temp = (-b + Math.Sqrt(my_var)) / (2 * a);
double raiz1 = temp.CompareTo(Double.NaN) < 1 ? 0.00 : temp;
temp = (-b + Math.Sqrt(-1 * my_var)) / (2 * a);
double raiz2 = temp.CompareTo(Double.NaN) < 1 ? 0.00 : temp;
Console.WriteLine($"Raiz1: {raiz1}\tRaiz2: {raiz2}");
Output:
97
NaN
Raiz1: 0.356107225224513 Raiz2: 0
The roots of the second degree equations are complex numbers in general case, e.g.
x**2 + 1 = 0
That's why I suggest using Complex, not float:
...
using System.Numerics;
...
// float.Parse - if you want to allow just real coefficients
Complex a = float.Parse(Console.ReadLine());
Complex b = float.Parse(Console.ReadLine());
Complex c = float.Parse(Console.ReadLine());
Complex bhaskarap1 = b * b - 4 * a * c;
Complex raiz1 = (-b + Complex.Sqrt(bhaskarap1)) / (2 * a);
Complex raiz2 = (-b - Complex.Sqrt(bhaskarap1)) / (2 * a);
Console.WriteLine(raiz1);
Console.WriteLine(raiz2);

Calculating floating point error bound

I have geometrical algorithms and im struggling with floating point inaccuracies.
For example, I'm calculating wether a point lies on the left/right/on a plane (C#):
const double Epsilon = 1e-10;
internal double ComputeDistance(Vector3D v)
{
Vector3D normal = Plane.Normal;
Vertex v0 = Plane.Origin;
double a = normal.X;
double b = normal.Y;
double c = normal.Z;
double d = -(a * v0.X + b * v0.Y + c * v0.Z);
return a * v.X + b * v.Y + c * v.Z + d;
}
internal string DistanceSign(Vector3D v)
{
var distance = ComputeDistance(v);
return (distance > Epsilon ? "left" : (distance < -Epsilon ? "right" : "on"));
}
As shown in the code, I use a fixed Epsilon value.
But I don't trust this fixed epsilon because I don't know the size of the floating point error. If the fp error is bigger than my epsilon interval, then my algorithm will fail.
How can I make it robust? I have searched on the internet but haven't found a solution so far. I have read "What Every Computer Scientist Should Know About Floating-Point Arithmetic", it describes why fp errors occur but not how to solve them practically.
Edit
Here is a shewchuk predicate that doesn't seem work:
double[] pa = {0, 0};
double[] pb = {2 * Double.Epsilon, 0};
double[] pc = { 0, Double.Epsilon };
Assert.IsTrue(GeometricPredicates.Orient2D(pa, pb, pc) > 0);
The assertion fails because Orient2D return 0. The code is here
Edit2
Shouldn't it be possible to calculate an error bound by using the machine epsilon? According to wikipedia, the machine epsilon is an upper bound due to rounding. For double, it is 2^−53. So as I take it, when I have an arithmetic calculation:
double x = y + z
then the maximum error should be 2^−53. Shouldn't this fact enable the possiblity to calculate an appropriate epsilon? So two rewrite my method:
double const Machine_Eps = 1.11022302462516E-16 // (2^-53)
double Epsilon = Machine_Eps;
internal double ComputeDistance(Vector3D v)
{
Vector3D normal = Plane.Normal;
Vertex v0 = Plane.Origin;
double a = normal.X;
double b = normal.Y;
double c = normal.Z;
// 3 multiplications + 2 additions = maximum of 5*Machine_Eps
double d = -(a * v0.X + b * v0.Y + c * v0.Z);
// 3 multiplications + 3 additions = maximum of 6*Machine_Eps
Epsilon = 11 * Machine_Eps;
return a * v.X + b * v.Y + c * v.Z + d;
}
internal string DistanceSign(Vector3D v)
{
var distance = ComputeDistance(v);
return (distance > Epsilon ? "left" : (distance < -Epsilon ? "right" : "on"));
}
Ok now you can tell me how wrong I am. :)

C# Floating Point Accuracy

Trying to create a Mandelbrot set, I have been trying to using 8 and 15 digit floating point variables in my program, and have run into an issue: the double approximates to 0. I tried unit testing and wrote this code to isolate the issue. Using the variable viewer, the h and w values both were on 0.0, as opposed to 0.00185185185185 and 0.0015625, yet when I just write double h = 0.0015625, it works.
Many thanks for assistance.
int apparentwidth = 3;
int apparentheight = 2;
int height = 1080;
int width = 1920;
double w = (apparentwidth / width);
double h = (apparentheight / height);
Console.WriteLine(w);
Console.WriteLine(h);
You're dividing two int variables, and the result is an int. You're storing the result in a double, but the scale (portion after the decimal) has already been lost.
Use double throughout:
double apparentwidth = 3;
double apparentheight = 2;
double height = 1080;
double width = 1920;
double w = (apparentwidth / width);
double h = (apparentheight / height);
Or cast one of the variables to a double when dividing:
double w = ((double)apparentwidth / width);
double h = ((double)apparentheight / height);
You are doing integer division on accident.
double w = (double)apparentwidth / (double)width;
double h = (double)apparentheight / (double)height;
Just to provide further explanation to the other answers:
When you do mathematical operations on ints, the result is an int, and this is achieved by effectively truncating the non-integer portion:
3 / 2 == 1
When an operation is performed involving at least one double, the int input is first converted to a double, so the result is a double:
1.0 / 4 == 0.25
4 * 0.25 == 1
And of course, if both inputs are double the result is double and no implicit conversion occurs:
1.0 / 4.0 == 0.25

Get value between a range of two values from percentage

Let's say I have a range of two values:
5...........98
and let's assume the user position's the slider at value 40
Now I want to get the value from another range of values at the exact percentage position as from range 1
let's say the second range of values are 10.........80
int nRange1 = 98 - 5;
int nRange2 = 80 - 10;
int nValue1 = 40;
int nPercentOnRange1 = ((nValue1 - 5) / nRange1)*100;
Now I have to get the value from Range2 at the exact percentage as nPercentOnRange1, but I don't know how
First need to find % from first range and apply that % to new range.
Here is what I will do:
Range1(A to B) Selected value: c
Range2(E to F)
Range1 % = (C-A) / (B-A) * 100
Range 2 corresponding value = ((F - E) * (Range 1 %) / 100) + E
C#:
int Range1Min = 5, Range1Max=90, Range1SelectedValue = 40;
int Range2Min = 6, Range2Max=80;
decimal range1Percent = (Range1SelectedValue-Range1Min ) / (Range1Max-Range1Min) * 100.0
decimal range2NewValue = (Range2Max - Range2Min) * range1Percent / 100 + Range2Min;
Watch out for
int nPercentOnRange1 = ((nValue1 - 5)/ nRange1) * 100;
ending up as zero since nValue1 and nRange1 are integers. This might be better:
int nPercentOnRange1 = ((nValue1 - 5) * 100 / nRange1);
Then you can do
int nValue2 = 10 + nPercentOnRange1*nRange2/100;
The value you need is
x = 10 + nRange2 * nPercentOnRange1 / 100.0
Let me explain why. You need a number x such that
((x - 10) / nRange2) * 100.0 = nPercentOnRange1
Therefore, just solve for x.
((x - 10) / nRange2) * 100.0 = nPercentOnRange1 =>
((x - 10) / nRange2) = nPercentOnRange1 / 100.0 =>
x - 10 = nRange2 * nPercentOnRange1 / 100.0 =>
x = 10 + nRange2 * nPercentOnRange1 / 100.0
And note that this actually makes intuitive sense. We're saying take the percentage, scale that into the length of the second range (that's what nRange2 * nPercentOnRange1 / 100.0) is doing and then add that to the lower bound of the second range. Basically we are saying step nPercentOnRange1 percent into the second range. That's exactly what the formula is expressing.
Perhaps this will work:
nValue2 = nPercentage1 * nRange2 / 100 + 10

Categories