The result of calculation deviates after some digits [duplicate] - c#

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
Result of calculation shown below should be equal to 0,007306897 (I referred from 2 books) . But when i check result from Watch 1, i see that result is equal to 0,007306882. I split the process into some parts. And the problem is occurring when c is calculating.
///Declarations
double sigma = 1.00000000;
double a,b,e,c;
a = (1 / Math.Sqrt(2 * Math.PI)); //calculated properly
c = -(i * i + j * j) / 2.00000000 * (sigma * sigma); //i and j are equal to -2
e = Math.E; //calculated properly
b = Math.Pow(e, c);
result=a * b;

Unfortunately the double type is not highly accurate. The link below shows that some numbers like 1.05 can not be stored accurately by the double type.
http://www.binaryconvert.com/convert_double.html
For normal usage it is usually accurate enough, if you need accuracy to the level you describe you probably need to use something like binary coded decimal. That will mean the normal math library won't work. You could try asking on some physics sites to see what they use when modelling complex systems to maintain accuracy.

Related

Math Operation in Windows Form Application [duplicate]

This question already has answers here:
Why does integer division in C# return an integer and not a float?
(8 answers)
Closed 1 year ago.
I am trying to use a function in windows form application that convert a given point to another coordinate system. However, I encountered a strange problem. The input are correct but output is always 0. First, I thought it caused because of the local variables and then instead of variables I used only integers but it did not solve. I have no idea about it. Here the code and output basically:
string[] newPoint1 = convertPoints(X1, Y1);
string[] convertPoints(int oldX, int oldY)
{
//int newX = ((oldX - oldLeft) / (oldRight - oldLeft)) * (newRight - newLeft);
MessageBox.Show(oldX.ToString()); // output is 296
int newX = (oldX / 500) * 4096; // ????????????????????? (296/500) * 4096 = 0 ?????????????
MessageBox.Show(newX.ToString()); // here output is 0
int newY = newTop + ((oldY - oldTop) / (oldBottom - oldTop)) * (newBottom - newTop);
//MessageBox.Show(newY.ToString());
string[] newPoints = {newX.ToString(), newY.ToString()};
//MessageBox.Show(newPoints[0], newPoints[1]);
return newPoints;
}
This is working as it should. Because oldX is an Integer, when you divide it, it rounds (drops anything after the decimal). I would convert it to float and back into an integer, like so
int newX = (int)(((float)oldX / 500) * 4096);
This will preserve the whole number until you're done at the end. You'll also need to do the same for the Y values
An integer division cuts off the decimal places. So in your case, 296/500 you would expect 0.592. As integer has no decimal places, it cuts off them off resulting in 0.
Change the oldX to double and divide by 500.0
You are getting 0 because oldX/500 is a fraction usually and since you are using the int datatypes there can only be whole numbers. What I would recommend doing is changing the data type then rounding yourself.
//Old code
int newX = (1 / 500);
Console.WriteLine(newX);
// writes 0 to console
//New code
double newXD = (1 / 500.0) * 4096;
Console.WriteLine(newXD);
//Writes 8.192
The 1 and the 500 are considered ints try
Console.WriteLine(1/500);
It writes 0 to the console.
Console.WriteLine(1/500.0);
Console.WriteLine((float)1/500);
Console.WriteLine((double)1/500);
All these write 8.192 to the console.
Then after you have the double or other more accurate data type consider rounding if you really want an int.

How to restrict calculated value to four decimal places [duplicate]

This question already has answers here:
How do you round a number to two decimal places in C#?
(15 answers)
Closed 5 years ago.
I want to limit decimal place till 4 for below code, how to do that,
var a = Convert.ToDecimal( 80794992640) / (1024 * 1024);
I guess you can round it if you want to fix it to 4 digits:
var a = Math.Round(Convert.ToDecimal( 80794992640) / (1024 * 1024),4 );
but if your concern is to restrict it in the display then you can just apply the restriction in the ToString method:
a.ToString("0.####");
the latter method will keep the precision for the calculations but cut the precision only for display
This will round it to 4 decimal places:
var a = Math.Round(Convert.ToDecimal( 80794992640) / (1024 * 1024), 4);

Why does Math.Tan(90) provide a non-undefined value?

While working with Math.Tan() I found that the result for 90 degree is not undefined. But is, inturn 1.6331779e+16
Here is the screenshot for the app
Here is the code,
// convert to degrees
angle = (Convert.ToDouble(op1) * Math.PI / 180);
// write the output
FinalResult.Text = Math.Tan(Convert.ToDouble(angle)).ToString();
Why is such behaviour, is it expected?
This question has been addressed (and answered, quite thoroughly) over on https://math.stackexchange.com/ in the question Why does the google calculator give tan 90 degrees = 1.6331779e+16?
or in other words ... You need to read David Goldberg's paper, What Every Computer Scientist Should Know About Floating-Point Arithmetic. You can purchase a copy from the ACM (or download one if you are a member of the ACM) at http://dl.acm.org/citation.cfm?id=103163. Other versions are available, gratis, as well.
A copy of the original is at http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf. Also:
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Double/paper.pdf
And CiteSeer links to other locations as well:
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.6768
The calculation is done with floating point numbers which are not perfect (not that Math.PI can ever be perfectly represented as a decimal anyways).
http://en.wikipedia.org/wiki/Floating_point
and more specifically..
https://math.stackexchange.com/questions/536144/why-does-the-google-calculator-give-tan-90-degrees-1-6331779e16
If you want a rounded result then check the input for something like >89.9999 && <90.00001. Don't use == with floating point values.
For explanation of why not to use == with floating point numbers, try running this example:
var d = 0.2;
for(double k = 1.0; k<100; k++) {
var t = 0.2 * k;
t = t / k;
Console.WriteLine("{0} == {1} ==> {2}", d, t, d == t);
}
We're multiplying 0.2 by a whole number, dividing it by the same whole number, and then comparing to 0.2. It should be true every time, right? It's not. Many times it returns false.

C# Square root expression just won't work

I've got a very simple little program to solve quadratic equations, in the main it works but for some reason it won't calculate square roots. I just get an error saying NaN but I can't see how it's not a number?
int a = Convert.ToInt16(txta.Text);
int b = Convert.ToInt16(txtb.Text);
int c = Convert.ToInt16(txtc.Text);
listBox1.Items.Add(Convert.ToString(Math.Sqrt(((b * b) - (4 * a * c)))));
The conversions aren't the cause because if they didn't convert properly or if there was an overflow you'd get a FormatException or OverflowException respectively. None the less, since you're doing math you might want to convert to double types.
double a = Convert.ToDouble(txta.Text);
double b = Convert.ToDouble(txtb.Text);
double c = Convert.ToDouble(txtc.Text);
I believe your expression: (b * b) - (4 * a * c) is the problem. If it evaluates to a negative number, that will result in a NaN result.
See Math.Sqrt Method on MSDN for more information.
It's likely getting a negative number. It might help to convert it to a double instead of an Int16, because Int16 will round every time.

Rounding double value to value ending on .0 or .5 [duplicate]

This question already has answers here:
How do I round to the nearest 0.5?
(10 answers)
Closed 9 years ago.
I'm trying to round some values as the following examples and need some help to write the math calculation for it:
input -> 25 ÷ 4 = 6.25 output -> 6.5
input -> 15.5 ÷ 4 = 3.875 output -> 4.0
input -> 24.5 ÷ 4 = 6.125 output -> 6.0
any idea how to write the round math procedure please?!
This should do it.
double Divide(double numerator, double denominator)
{
double result = numerator / denominator;
//round to nearest half-integer
result = Math.Round(result * 2, MidpointRounding.AwayFromZero) / 2;
// due to peculiarities of IEEE754 floating point arithmetic
// we need to round again after dividing back by two
// to avoid a result like 1.49999999.
return Math.Round(result, 1);
}
Sorry for not aware the difficulty you encountered, so I guess maybe the different types of floating point number. Following code just does that:
public static decimal RoundedDivide<T>(T a, T b) {
var x=2*Convert.ToDecimal(a)/Convert.ToDecimal(b);
x=((int)(.5m+x)>x?1:0)+(int)x;
return x/2;
}
Two things to note:
I cannot bound a constraint of ValueType, so if you pass objects of reference types, it may throw
If you wish double as the return type, then just change it and also change .5m to .5, Convert.ToDecimal to Convert.ToDouble

Categories