Reputation: 331
In my C# app I am reading numeric data from my MySQL table. After that, I am searching for a minimal euclidean distance (between table row and an average tuple).
I am reading values from MySQL table into double variables (f1
to f8
and one int
variable). I am getting this error on the first line, where I am putting the reader's result into f1
. However, when I do random computation after reading my values for example (f1
+f8
), it returns right/exact result. So why does C# have a problem with the input string?
Here is my code:
for (int k = 1; k <= pocet; k++)
{
string queryCompare = " SELECT F1 AS Fe1, F2 AS Fe2, F3 AS Fe3, F4 AS Fe4, F5 AS Fe5, F6 AS Fe6, F7 AS Fe7, F8 AS Fe8, cluster FROM features WHERE ID=" + k;
MySqlCommand cmdCompare = new MySqlCommand(queryCompare, conect);
readerCompare = cmdCompare.ExecuteReader();
readerCompare.Read();
// MessageBox.Show("OK");
double f1 = Convert.ToDouble(readerCompare["Fe1"].ToString()); // EXCEPTION HERE
double f2 = Convert.ToDouble(readerCompare["Fe2"].ToString());
double f3 = Convert.ToDouble(readerCompare["Fe3"].ToString());
double f4 = Convert.ToDouble(readerCompare["Fe4"].ToString());
double f5 = Convert.ToDouble(readerCompare["Fe5"].ToString());
double f6 = Convert.ToDouble(readerCompare["Fe6"].ToString());
double f7 = Convert.ToDouble(readerCompare["Fe7"].ToString());
string f88 = readerCompare["Fe8"].ToString();
double f8 = Convert.ToDouble(f88, CultureInfo.InvariantCulture);
int cluster = Convert.ToInt32(readerCompare["cluster"].ToString());
readerCompare.Close();
// MessageBox.Show((f1+f8).ToString());
switch (cluster)
{
case 1:
euklDist = (double)Math.Sqrt(
Math.Pow(touple[0, 0] - f1, 2) +
Math.Pow(touple[0, 1] - f2, 2) +
Math.Pow(touple[0, 2] - f3, 2) +
Math.Pow(touple[0, 3] - f4, 2) +
Math.Pow(touple[0, 4] - f5, 2) +
Math.Pow(touple[0, 5] - f6, 2) +
Math.Pow(touple[0, 6] - f7, 2) +
Math.Pow(touple[0, 7] - f8, 2));
if (euklDist < minCl1)
{
minCl1 = euklDist;
idCl1 = k;
}
break;
case 2:
euklDist = (double)Math.Sqrt(
Math.Pow(touple[1, 0] - f1, 2) +
Math.Pow(touple[1, 1] - f2, 2) +
Math.Pow(touple[1, 2] - f3, 2) +
Math.Pow(touple[1, 3] - f4, 2) +
Math.Pow(touple[1, 4] - f5, 2) +
Math.Pow(touple[1, 5] - f6, 2) +
Math.Pow(touple[1, 6] - f7, 2) +
Math.Pow(touple[1, 7] - f8, 2));
if (euklDist < minCl2)
{
minCl2 = euklDist;
idCl2 = k;
}
break;
case 3:
euklDist = (double)Math.Sqrt(
Math.Pow(touple[2, 0] - f1, 2) +
Math.Pow(touple[2, 1] - f2, 2) +
Math.Pow(touple[2, 2] - f3, 2) +
Math.Pow(touple[2, 3] - f4, 2) +
Math.Pow(touple[2, 4] - f5, 2) +
Math.Pow(touple[2, 5] - f6, 2) +
Math.Pow(touple[2, 6] - f7, 2) +
Math.Pow(touple[2, 7] - f8, 2));
if (euklDist < minCl3)
{
minCl3 = euklDist;
idCl3 = k;
}
break;
}
}
Records in my db are in this format:
xx,xxx
xx.xxx
I know that f8
has decimal point instead of comma that is why I am using CultureInfo.InvariantCulture
for f8
.
Upvotes: 2
Views: 526
Reputation: 67898
You don't need to update the null
values, just do this:
Convert.ToDouble(readerCompare["Fe1"]);
The null
will be handled by ToDouble
and convert it to its default value; 0
.
See, here is the ToDouble
implementation you'd be using with the above code:
public static double ToDouble(object value)
{
if (value != null)
return ((IConvertible) value).ToDouble((IFormatProvider) null);
else
return 0.0;
}
UPDATE: alright if you also need to support empty strings then you'll have to change this code a little. First let's build an extension method. Create a new class
in your solution and name it SystemExtensions
, then paste in this code:
namespace System
{
public static class SystemExtensions
{
public static string ToConvertibleDouble(this object input)
{
var s = input as string;
if (string.IsNullOrEmpty(s.Trim())) { return null; }
// this will also take care of the separator
return s.Replace(".", ",");
}
}
}
and now let's use it:
Convert.ToDouble(readerCompare["Fe1"].ToConvertibleDouble());
Convert.ToDouble(readerCompare["Fe2"].ToConvertibleDouble());
...
Convert.ToDouble(readerCompare["Fe8"].ToConvertibleDouble());
Upvotes: 3