How to get 0 from subtracting two double numbers? - c#

For some reason im getting a 2.7234235252E -17 instead of 0 when my program is subtracting .1 - .1, why is that? and how can i properly subtract? and as a third question, if i do subtract .1 - .1, does bool consider it 0? for example: 0 == .1 - .1 = true or false?
List<string> hd1List = new List<string>();
double hd1CD = 0;
double hd2CD = 0;
double hd3CD = 0;
double hd4CD = 0;
// for (int i = 0; i < 10; i++)
// {
if (hd1CD <= 0)
{
hd1List.Add("q");
hd1CD = 4;
hd1CD = hd1CD - .7;
}
Console.WriteLine(hd1CD);
Console.WriteLine(hd2CD);
Console.WriteLine(hd3CD);
Console.WriteLine(hd4CD);
if (hd2CD <= 0 && hd1CD >= .7)
{
hd1List.Add("e");
hd2CD = 1;
hd1CD = hd1CD - .7;
hd2CD = hd2CD - .7;
}
Console.WriteLine(hd1CD);
Console.WriteLine(hd2CD);
Console.WriteLine(hd3CD);
Console.WriteLine(hd4CD);
if (hd3CD <= 0 && hd1CD >= .2 && hd2CD >= .2)
{
hd1List.Add("r");
hd3CD = 5;
hd1CD = hd1CD - .2;
hd2CD = hd2CD - .2;
hd3CD = hd3CD - .2;
}
Console.WriteLine(hd1CD);
Console.WriteLine(hd2CD);
Console.WriteLine(hd3CD);
Console.WriteLine(hd4CD);
if (hd4CD <= 0 && hd1CD >= .1 && hd2CD >= .1 && hd3CD >= .1)
{
hd1List.Add("w");
hd4CD = 3;
hd1CD = hd1CD - .1;
hd2CD = hd2CD - .1;
hd3CD = hd3CD - .1;
hd4CD = hd4CD - .1;
}
Console.WriteLine(hd1CD);
Console.WriteLine(hd2CD);
Console.WriteLine(hd3CD);
Console.WriteLine(hd4CD);
if (hd4CD < 1.2 || hd1CD < 1.2 || hd2CD < 1.2 || hd3CD < 1.2 && hd4CD != 0 && hd1CD != 0 && hd2CD != 0 && hd3CD !=0)
The above is checking whether the variables hold 0, since im getting epsilon values my program cant run correctly...
{
//get minimum
hd1List.Add("extra" + superList.Min());
hd1CD = hd1CD - superList.Min();
hd2CD = hd2CD - superList.Min();
hd3CD = hd3CD - superList.Min();
hd4CD = hd4CD - superList.Min();
}
Summary: how do i re-arrange my code so that if i subtract .1 - .1, it = 0 and not a ridiculous number, i dont need advice, i need an example

You should not compare double values with ==. E.g. having code like
if (value==0) { /* do something here*/ }
is a bad idea if value is a double.
Instead you can do something like:
if (Math.Abs(value) < EPSILON) { /* do something here*/ }
where EPSILON is some small positive number/constant e.g. 1e-5.

Although you have a very good answer I thought I'd have a go at refactoring your code. Have a try of this:
List<string> hd1List = new List<string>();
double[] hdCDs = new double[4];
double EPSILON = 0.00000001;
Action<int, double, double, string> update = (i, v, d, t) =>
{
if (hdCDs[i] <= 0.0 && hdCDs.Take(i).All(x => x >= d))
{
hd1List.Add(t);
hdCDs[i] = v;
for (int x = 0; x <= i + 1; x++)
{
hdCDs[x] =- d;
}
}
Console.WriteLine(String.Join(Environment.NewLine, hdCDs));
};
update(0, 4.0, 0.7, "q");
update(1, 1.0, 0.7, "e");
update(2, 5.0, 0.2, "r");
update(3, 4.0, 0.1, "w");
if (hdCDs.Any(x => x < 1.2) && hdCDs.All(x => x <= EPSILON))
{
var min = superList.Min();
hd1List.Add("extra" + min);
for (int x = 0; x < hdCDs.Length; x++)
{
hdCDs[0] -= min;
}
}

Related

(C#) How can I make all these "else if" statements more condensed and how can I optimize my code better?

Okay, I have a load of else if statements, is there a way to condense them into fewer lines of code? Like make one if statement for all of it? And what ways could I make my code more optimize and easier to read?
int x;
int y;
int time=0;
Random rng = new Random();
int hrand_num = rng.Next(-24000, 24000);
int vrand_num = rng.Next(-24000, 24000);
x = hrand_num;
y = vrand_num;
while (true)
{
ConsoleKey key = Console.ReadKey().Key;
if (key == ConsoleKey.UpArrow)
{
y=y+2000;
}
else if (key == ConsoleKey.DownArrow)
{
y=y-2000;
}
else if (key == ConsoleKey.LeftArrow)
{
x = x-1000;
}
else if (key == ConsoleKey.RightArrow)
{
x = x+1000;
}
// Circumnavigate Players Position.
// North and South
if (y >= 24001)
{
y = -24000;
}
else if (y <= -24001)
{
y = 24000;
}
//West and East
else if (x >= 24001)
{
x = -24000;
}
else if (x <= -24001)
{
x = 24000;
}
// Setting Time Zones
if (x >= -2000 && x <= 0 )
{
time = 0;
}
else if (x >=
1 && x <= 2000)
{
time = 1;
}
else if (x >= 2001 && x <=4000)
{
time = 2;
}
else if (x >= 4001 && x <= 6000)
{
time = 3;
}
else if (x >= 6001 && x <= 8000)
{
time = 4;
}
else if (x >= 8001 && x <= 10000)
{
time = 5;
}
else if (x >= 10001 && x <= 12000)
{
time = 6;
}
else if (x >= 12001 && x <= 14000)
{
time = 7;
}
else if (x >= 14001 && x <= 16000)
{
time = 8;
}
else if (x >= 16001 && x <= 18000)
{
time = 9;
}
else if (x >= 18001 && x <= 20000)
{
time = 10;
}
else if (x >= 20001 && x <= 22000)
{
time = 11;
}
else if (x >= 22001 && x <= 24000)
{
time = 12;
}
else if (x == -24000 && x <= -22001)
{
time = 13;
}
else if (x >= -22000 && x <= -20001 )
{
time = 14;
}
else if (x >= -20000 && x <= -18001)
{
time = 15;
}
else if (x >= -18000 && x <= -16001)
{
time = 16;
}
else if (x >= -16000 && x <= -14001)
{
time = 17;
}
else if (x >= -14000 && x <= -12001)
{
time = 18;
}
else if (x >= -12000 && x <= -10001)
{
time = 19;
}
else if (x >= -10000 && x <= -8001)
{
time = 20;
}
else if (x >= -8000 && x <= -6001)
{
time = 21;
}
else if (x >= -6000 && x <= -4001)
{
time = 22;
}
else if (x >= -4000 && x <= -2001)
{
time = 23;
}
Console.WriteLine($"X: {x,6} Y: {y,6} Time: {time,3}");
}
```
Assuming that you are using C# 8.0 you may have a look at the switch statement and switch expressions: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/switch-expression (additionaly the patterns documentation is also helpful: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/patterns)
So you could write something like:
switch (key)
{
case ConsoleKey.UpArrow:
y=y+2000;
break;
// [...]
}
time = x switch
{
>= -2000 and <= 0 => 0,
>= 1 and <= 2000 => 1
// [...]
};
I would suggest that you take advantage of:
a switch statement for interpreting the arrow key
comparing the switch statement to an if loop, you can think of the first case as being the if condition and the remaning cases as being the else if conditions
Math.Abs( ) and Math.Sign( ) for circumnavigating the player's position
Math.Abs( ) returns the absolute value of the variable; e.g. will Math.Abs(x) return 5 both for x = 5 and x = -5
Math.Sign( ) returns the sign of the value; if the value is a negative number, it returns -1; if it's a positive number, it returns 1; if it's neither (0), it returns 0. This helps us determine the wanted sign of the updated value.
a switch expression for setting the time
seeing as the time value alone is determined by x in the end, you can use a switch expression rather than a switch statement to determine its value. The switch expression says that you want to determine the value of time based on the value of x; and each following condition is compared to x (<= -22001 is computed as x <= -22001). If the condition evaluates to true, the provided value is set as the value of time (=> 13 then sets time = 13).
It could be implemented like this:
int x;
int y;
Random rng = new Random();
int hrand_num = rng.Next(-24000, 24000);
int vrand_num = rng.Next(-24000, 24000);
x = hrand_num;
y = vrand_num;
while (true)
{
switch (Console.ReadKey().Key)
{
case ConsoleKey.UpArrow:
y += 2000;
break;
case ConsoleKey.DownArrow:
y -= 2000;
break;
case ConsoleKey.LeftArrow:
x -= 1000;
break;
case ConsoleKey.RightArrow:
x += 1000;
break;
}
// Circumnavigate Players Position.
// North and South
if (Math.Abs(y) > 24000)
{
y = -(Math.Sign(y) * 24000);
}
//West and East
else if (Math.Abs(x) > 24000)
{
x = -(Math.Sign(x) * 24000);
}
// Setting Time Zones
var time = x switch
{
<= -22001 => 13,
<= -20001 => 14,
<= -18001 => 15,
<= -16001 => 16,
<= -14001 => 17,
<= -12001 => 18,
<= -10001 => 19,
<= -8001 => 20,
<= -6001 => 21,
<= -4001 => 22,
<= -2001 => 23,
<= 0 => 0,
<= 2000 => 1,
<= 4000 => 2,
<= 6000 => 3,
<= 8000 => 4,
<= 10000 => 5,
<= 12000 => 6,
<= 14000 => 7,
<= 16000 => 8,
<= 18000 => 9,
<= 20000 => 10,
<= 22000 => 11,
<= 24000 => 12,
_ => 0
};
Console.WriteLine($"X: {x,6} Y: {y,6} Time: {time,3}");
I would also suggest introducing some constants; particularily for the value 24000.
You can use the following to cover all time cases
var time = x <= 24000
? x / 2000 + 1;
: (24000 - x) / 2000 + 13;

Determination of pixels which are included in the loop's bounds

This program works with Median filter. I need help with fixing the code. It applies to the line
if ((diffX > -1) && (diffY > -1)...
...in the MedianOfArea method. It would be better if the pixels, which are included in the loop's bounds, would be determined initially. This solution helps to avoid checking every time. Can you help me with fixing it?
namespace Recognizer
{
internal static class MedianFilterTask
{
public static double[,] MedianFilter(double[,] original)
{
var filter = new double[original.GetLength(0), original.GetLength(1)];
var lengthX = original.GetLength(0);
var lengthY = original.GetLength(1);
for (var x = 0; x < lengthX; x++)
for (var y = 0; y < lengthY; y++)
filter[x, y] = MedianOfArea(x, y, original, lengthX, lengthY);
return filter;
}
public static double MedianCount(ref double median, List<double> pixelsFields)
{
pixelsFields.Sort();
var countPixels = pixelsFields.Count;
if (countPixels % 2 == 0)
median = (pixelsFields[countPixels / 2 - 1] + pixelsFields[countPixels / 2]) / 2;
else
median = pixelsFields[countPixels / 2];
return median;
}
public static double MedianOfArea(int x, int y, double[,] original, int lengthX, int lengthY)
{
var pixelsFields = new List<double>();
double median = 0;
for (int areasX = -1; areasX < 2; areasX++)
for (int areasY = -1; areasY < 2; areasY++)
{
var diffX = x + areasX;
var diffY = y + areasY;
if ((diffX > -1) && (diffY > -1) && (diffX < lengthX) && (diffY < lengthY))
pixelsFields.Add(original[diffX, diffY]);
}
MedianCount(ref median, pixelsFields);
return median;
}
}
}
You could iterate directly on diffX (and diffY) and use Min and Max to set the ranges to loop over:
using System;
int startX = Math.Max(0, x-1);
int endX = Math.Min(lengthX, x+2);
int startY = Math.Max(0, y-1);
int endY = Math.Min(lengthY, y+2);
for (int diffX = startX; diffX < endX; diffX++)
for (int diffY = startY; diffY < endY; diffY++)
pixelsFields.Add(original[diffX, diffY]);

How to use the method of Monte Carlo to search for the limit probabilities

I want to understand how to use the method of Monte Carlo to search for the limit probabilities of the some system S.
For example:
S0 S1 S2 S3
S0 0.1 0.9 0 0
S1 0 0.2 0.3 0.5
S2 0.2 0.1 0.5 0.2
S3 0.5 0 0.4 0.1
As I understand the method we need to generate a some number (x) and then compare the probability:
if x
0 <= x < 0.1 => S0 -> S0
0.1 <= x < 0.9 => S0 -> S1
0.9 <= x < 0.9 => S0 -> S2
0.9 <= x < 0.9 => S0 -> S3
0.9 <= x < 1 => S0 -> S4
when S4 - limit (border)
Similarly for other states.
Following this approach I can count the number of transitions:
static double[] SimpleMonte(double[][] a, int iter = 1)
{
var n = a.GetLength(0);
var p =
a
.Select(x => x.Select((_, i) => x.Take(i + 1).Sum()).ToArray())
.ToArray();
Random rand = new Random();
double[] X = new double[n];
for (int x = 0; x < n; x++)
{
double count = 0;
for (int i = 0; i < iter; i++)
{
int row = x;
bool notG = true;
Console.Write("{0} -> ", row);
while (notG)
{
var e = rand.NextDouble();
Console.Write("({0})", Math.Round(e, 2));
bool ch = false;
for (int j = 0; j < n - 1; j++)
{
if (p[row][j] <= e && e < p[row][j + 1])
{
row = j + 1;
ch = true;
break;
}
}
if (!ch)
notG = false;
else
{
Console.Write("{0} -> ", row);
count++;
}
}
Console.WriteLine();
}
X[x] = count / iter;
}
return X;
}
https://dotnetfiddle.net/nJF5sm
I will be glad to hear a hint on what to do to solve this problem.
In a practical sense, the best way to find a limit of the a system like that is repeated squaring of the matrix until the entries converge. This works because it is a stochastic matrix (sum of each row equals 1). When I tried it I got an answer of:
S0 S1 S2 S3
0.1939252 0.2593458 0.3294393 0.2172897
which gives the average probabilities that you will be in a particular state.
To use a Monte Carlo method, you should generate the random numbers like you have done and keep count of the transitions. Then the average probability that you're in a certain state is
(Amount of Transitions to State S)/(Total Transitions)
as your Total Transitions gets large enough.
In the code you provided, if you keep increasing the size of your iter variable (and it does need to be relatively large) the last four lines of your output should converge to the numbers above. I hope that helps.
In the original code there was a mistake that prevented a transition to the initial state. That is the correct version:
static double[] SimpleMonte(double[][] a, int iter = 10000)
{
var n = a.GetLength(0);
var p =
a
.Select(x => x.Select((_, i) => x.Take(i + 1).Sum()).ToArray())
.ToArray();
Random rand = new Random();
double[] X = new double[n];
int row = rand.Next(n);
for (int i = 0; i < iter; i++)
{
var e = rand.NextDouble();
X[row]++;
if (e < p[row][0])
row = 0;
else
for (int j = 0; j < n - 1; j++)
{
if (p[row][j] <= e && e < p[row][j + 1])
{
row = j + 1;
break;
}
}
}
return X.Select(x => x / iter).ToArray();
}

How to process an array correctly

Here's the part 1 of my question, if you wanna check the background of this question :
Detecting brackets in input string
Forgive me if the title doesn't match, since I also confused how to name it appropriately to picture my problem. If anyone knows a more appropriate title, feel free to edit.
So, given below code (my own code) :
private const int PARTICLE_EACH_CHAR = 4;
/*ProcessBarLines : string s only contains numbers, b, [, and ]*/
private int ProcessBarLines(Canvas canvas, string s, int lastLineAboveNotation)
{
List<int> bracket = new List<int>();
List<int> other = new List<int>();
int currentCloseNumber = 0;
int currentOpenNumber = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == '[')
{
bracket.Add(i);
currentOpenNumber++;
if (i - 1 > 0 && s[i - 1] != '[')
{
currentOpenNumber = 1;
}
}
else if (s[i] == ']')
{
bracket.Add(i);
currentCloseNumber++;
if (i + 1 >= s.Length || s[i + 1] != ']' || currentOpenNumber == currentCloseNumber)
{
int min = bracket.Count - (currentCloseNumber * 2);
int max = bracket[bracket.Count - 1];
List<int> proc = new List<int>();
int firstIndex = -1;
int lastIndex = -1;
for (int ii = 0; ii < other.Count; ii++)
{
if (other[ii] > min && other[ii] < max)
{
proc.Add(other[ii]);
if (firstIndex == -1)
{
firstIndex = ii;
lastIndex = ii;
}
else
{
lastIndex = ii;
}
}
}
double leftPixel = firstIndex * widthEachChar;
double rightPixel = (lastIndex * widthEachChar) + widthEachChar;
DrawLine(canvas, currentCloseNumber, leftPixel,
rightPixel, lastLineAboveNotation * heightEachChar / PARTICLE_EACH_CHAR);
lastLineAboveNotation += currentCloseNumber - 1;
currentOpenNumber -= currentCloseNumber;
currentCloseNumber = 0;
}
}
else
{
other.Add(i);
}
}
return lastLineAboveNotation + 1;
}
Here's the test cases :
Picture 1 & 2 is the correct answer, and picture 3 is the wrong answer. Picture 3 should have a line, just like inverted from number 2, but, apparently, (if you look closely) the line is drawn on the right, but it should be on the left to be correct (above 0).
I figured, the problem is, I'm quite sure on the "min". Since it doesn't give the correct starting value.
Any idea on this? Feel free to clarify anything. It's used for writing numeric musical scores.
Btw, DrawLine() just meant to draw the line above the numbers, it's not the problem.
Finally! I found it!
private int ProcessBarLines(Canvas canvas, string s, int lastLineAboveNotation)
{
List<int> bracket = new List<int>();
List<int> other = new List<int>();
int currentCloseNumber = 0;
int currentOpenNumber = 0;
int space = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == '[')
{
bracket.Add(i);
currentOpenNumber++;
if (i - 1 > 0 && s[i - 1] != '[')
{
currentOpenNumber = 1;
}
}
else if (s[i] == ']')
{
bracket.Add(i);
currentCloseNumber++;
if (i + 1 >= s.Length || s[i + 1] != ']' || currentOpenNumber == currentCloseNumber)
{
int min = bracket[Math.Max(bracket.Count - ((currentCloseNumber * 2) + space), 0)];
int max = bracket[bracket.Count - 1];
space = max - min - 1;
List<int> proc = new List<int>();
int firstIndex = -1;
int lastIndex = -1;
for (int ii = 0; ii < other.Count; ii++)
{
if (other[ii] > min && other[ii] < max)
{
proc.Add(other[ii]);
other[ii] = -1;
if (firstIndex == -1)
{
firstIndex = ii;
lastIndex = ii;
}
else
{
lastIndex = ii;
}
}
}
double leftPixel = firstIndex * widthEachChar;
double rightPixel = (lastIndex * widthEachChar) + widthEachChar;
DrawLine(canvas, currentCloseNumber, leftPixel,
rightPixel, lastLineAboveNotation * heightEachChar / PARTICLE_EACH_CHAR);
lastLineAboveNotation += 1;
currentOpenNumber -= currentCloseNumber;
currentCloseNumber = 0;
}
}
else
{
other.Add(i);
}
}
return lastLineAboveNotation + 1;
}
If someone got a more efficient code, please let us know!

How can I optimize my implementation of the "toExponential" algorithm to improve precision?

I feel like my implementation is a bit naive. Take notice of the variables min in max which have a rather small precision of +/- 0.0001. If I raise the precision any further the code is just too slow.
Algorithm
alt text http://img35.imageshack.us/img35/2060/toexponential.jpg
Code
private IDynamic ToExponential(Engine engine, Args args)
{
var x = engine.Context.ThisBinding.ToNumberPrimitive().Value;
if (double.IsNaN(x))
{
return new StringPrimitive("NaN");
}
var s = "";
if (x < 0)
{
s = "-";
x = -x;
}
if (double.IsPositiveInfinity(x))
{
return new StringPrimitive(s + "Infinity");
}
var f = args[0].ToNumberPrimitive().Value;
if (f < 0D || f > 20D)
{
throw new Exception("RangeError");
}
var m = "";
var c = "";
var d = "";
var e = 0D;
var n = 0D;
if (x == 0D)
{
f = 0D;
m = m.PadLeft((int)(f + 1D), '0');
e = 0;
}
else
{
if (!args[0].IsUndefined) // fractionDigits is supplied
{
var lower = (int)Math.Pow(10, f);
var upper = (int)Math.Pow(10, f + 1D);
var min = 0 - 0.0001;
var max = 0 + 0.0001;
for (int i = lower; i < upper; i++)
{
for (int j = (int)f; ; --j)
{
var result = i * Math.Pow(10, j - f) - x;
if (result > min && result < max)
{
n = i;
e = j;
goto Complete;
}
if (result <= 0)
{
break;
}
}
for (int j = (int)f + 1; ; j++)
{
var result = i * Math.Pow(10, j - f) - x;
if (result > min && result < max)
{
n = i;
e = j;
goto Complete;
}
if (result >= 0)
{
break;
}
}
}
}
else
{
var min = x - 0.0001;
var max = x + 0.0001;
// Scan for f where f >= 0
for (int i = 0; ; i++)
{
// 10 ^ f <= n < 10 ^ (f + 1)
var lower = (int)Math.Pow(10, i);
var upper = (int)Math.Pow(10, i + 1D);
for (int j = lower; j < upper; j++)
{
// n is not divisible by 10
if (j % 10 == 0)
{
continue;
}
// n must have f + 1 digits
var digits = 0;
var state = j;
while (state > 0)
{
state /= 10;
digits++;
}
if (digits != i + 1)
{
continue;
}
// Scan for e in both directions
for (int k = (int)i; ; --k)
{
var result = j * Math.Pow(10, k - i);
if (result > min && result < max)
{
f = i;
n = j;
e = k;
goto Complete;
}
if (result <= i)
{
break;
}
}
for (int k = (int)i + 1; ; k++)
{
var result = i * Math.Pow(10, k - i);
if (result > min && result < max)
{
f = i;
n = j;
e = k;
goto Complete;
}
if (result >= i)
{
break;
}
}
}
}
}
Complete:
m = n.ToString("G");
}
if (f != 0D)
{
m = m[0] + "." + m.Substring(1);
}
if (e == 0D)
{
c = "+";
d = "0";
}
else
{
if (e > 0D)
{
c = "+";
}
else
{
c = "-";
e = -e;
}
d = e.ToString("G");
}
m = m + "e" + c + d;
return new StringPrimitive(s + m);
}
Final Version
I swear someone must have hit me with a particularly large hammer back when I originally wrote this...
private IDynamic ToExponential(Engine engine, Args args)
{
var x = engine.Context.ThisBinding.ToNumberPrimitive().Value;
if (args[0].IsUndefined)
{
return new StringPrimitive(x.ToString("0.####################e+0"));
}
var f = args[0].ToNumberPrimitive().Value;
if (f < 0D || f > 20D)
{
RuntimeError.RangeError("The parameter fractionDigits must be between 0 and 20.");
}
return new StringPrimitive(x.ToString("0." + string.Empty.PadRight((int)f, '0') + "e+0"));
}
When you compute result = i * Math.Pow(10, j - f) - x you're trying to find where result is 0. Since j, f, and x are know, you just need to solve for i. Rather than writing a loop to find i, you can just say
i * Math.Pow(10, j - f) = x => i = x / Math.Pow(10, j - f)
The value you need should be either floor(i) or ceil(i).
Just out of curiosity, have you checked to see if ToString("e") gives you the correct answer?
I'd start by using Math.Log10, rather than a loop, to find the exponent.

Categories

Resources