I need to compare numeric data from two datatables with the same schema.
For example two tables with data such as
PKColumn | numCol | DecimalCol
will end up looking like this after the merge
PKColumn | numCol 1 | numCol 2 | numCol Diff | DecimalCol 1 | DecimalCol 2 | DecimalCol Diff
Initially, I just created the diff column as an expression col1-col2 but I can end up with unusual looking values
col1 col2 diff c1 c2 diff
12.8 14.6 -1.80000019 33.2 29.8 3.40000153
But what I want is:
col1 col2 diff c1 c2 diff
12.8 14.6 -1.8 33.2 29.8 3.4
So my current solution is to manually iterate through the rows and set the value using this method:
private static void SetDifference(DataRow dataRow, DataColumn numericColumn)
{
dynamic value1 = dataRow[numericColumn.Ordinal - 2];
dynamic value2 = dataRow[numericColumn.Ordinal - 1];
if (IsDbNullOrNullOrEmpty(value1) || IsDbNullOrNullOrEmpty(value2)) return;
//now find out the most decimals used and round to this value
string valueAsString = value1.ToString(CultureInfo.InvariantCulture);
int numOfDecimals = valueAsString.SkipWhile(c => c != '.').Skip(1).Count();
valueAsString = value2.ToString(CultureInfo.InvariantCulture);
numOfDecimals = System.Math.Max(numOfDecimals, valueAsString.SkipWhile(c => c != '.').Skip(1).Count());
double result = Convert.ToDouble(value1 - value2);
dataRow[numericColumn] = System.Math.Round(result, numOfDecimals);
}
But it feels clunky and not good for performance. Suggestions for improvements are welcome.
EDIT: changed column names from “int” to “num” to avoid confusion
EDIT: also, I don’t always want to round to one decimal spot. I may have data like numA: 28 numB: 75.7999954 so I want a diff of: -47.7999954
If you have columns that store integer numbers then use an integer number type for them! Probably you used a single precision floating point type. The same holds for decimal types. Use a decimal column type for them and this rounding problem will vanish!
If you use a true decimal type (not float, single, real or double) you will not encounter rounding problems. I do not know which database you are using, but with SQL-Server the correct column type would be
decimal.UPDATE
Since you cannot change the column type, round it to the requested precision like this
—
UPDATE
Try this, it should perform well in most cases
Test