我需要比较两个数据表中具有相同模式的数值数据。 例如,两个表格包含
等数据合并后PKColumn | numCol | DecimalCol
最终会看起来像这样
PKColumn | numCol 1 | numCol 2 | numCol Diff | DecimalCol 1 | DecimalCol 2 | DecimalCol Diff
最初,我刚刚将diff列创建为表达式col1-col2,但我最终会看到不寻常的值
col1 col2 diff c1 c2 diff
12.8 14.6 -1.80000019 33.2 29.8 3.40000153
但我想要的是:
col1 col2 diff c1 c2 diff
12.8 14.6 -1.8 33.2 29.8 3.4
所以我目前的解决方案是手动迭代行并使用此方法设置值:
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);
}
但它感觉笨重而且不利于表现。欢迎提出改进建议。
编辑:将列名从“int”更改为“num”以避免混淆
编辑:此外,我并不总是希望舍入到一个小数点。我可能有像numA:28 numB:75.7999954这样的数据所以我想要一个差异:-47.7999954
答案 0 :(得分:1)
如果您有存储整数的列,那么为它们使用整数类型!可能你使用的是单精度浮点类型。小数类型也是如此。使用十进制列类型,这个舍入问题将消失!
如果使用真十进制类型(不是float,single,real或double),则不会遇到舍入问题。我不知道您使用的是哪个数据库,但使用SQL-Server时,正确的列类型为decimal
。
<强>更新强>
由于您无法更改列类型,请将其四舍五入为所需的精度,如此
result = Math.Round((c1-c2) * 10)/10; // One decimal
result = Math.Round((c1-c2) * 100)/100; // Two decimals
result = Math.Round((c1-c2) * 1000)/1000; // Three decimals
Math.Round(3.141592654 * 10000)/10000 ===> 3.1416
-
<强>更新强>
试试这个,它在大多数情况下应该表现良好
decimal result = (decimal)col1 - (decimal)col2;
测试
12.8f - 14.6f ===> -1.80000019 (decimal)12.8f - (decimal)14.6f ===> -1.8
答案 1 :(得分:1)
根据Olivier的评论,我已将代码更新为:
if(numericColumn.DataType == typeof(int))
{
dataRow[numericColumn] = System.Math.Abs(value1 - value2);
}
else
{
dataRow[numericColumn] = Convert.ToDecimal(value1) - Convert.ToDecimal(value2);
}
似乎更清洁,它完成了工作。 谢谢你的帮助。
答案 2 :(得分:0)
您应该使用
在sql查询中执行此操作ROUND(table1.IntCol 1 - table2.IntCol 2, 1)