0

我需要比较来自具有相同架构的两个数据表的数字数据。例如两个包含数据的表,例如

PK专栏 | 数列 | 小数列

合并后会变成这样

PK专栏 | 数列 1 | 数列 2 | numCol 差异 | 小数列 1 | 小数列 2 | DecimalCol 差异

最初,我只是将 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

4

3 回答 3

1

如果您有存储整数的列,则为它们使用整数类型!可能您使用了单精度浮点类型。十进制类型也是如此。为它们使用十进制列类型,这个舍入问题将消失!

如果您使用真正的十进制类型(不是浮点数、单数、实数或双精度数),您将不会遇到舍入问题。我不知道您使用的是哪个数据库,但对于 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
数学圆(3.141592654 * 10000)/10000 ===> 3.1416

--

更新

试试这个,它在大多数情况下应该表现良好

decimal result = (decimal)col1 - (decimal)col2;

测试

12.8f - 14.6f ===> -1.80000019

(十进制)12.8f - (十进制)14.6f ===> -1.8
于 2012-04-20T20:03:33.583 回答
1

根据 Olivier 的评论,我将代码更新为如下所示:

if(numericColumn.DataType == typeof(int))
{
    dataRow[numericColumn] = System.Math.Abs(value1 - value2);
}
else
{
    dataRow[numericColumn] = Convert.ToDecimal(value1) - Convert.ToDecimal(value2);
}

看起来更干净,它完成了工作。谢谢您的帮助。

于 2012-04-23T13:34:24.347 回答
0

您应该在 sql 查询中使用

ROUND(table1.IntCol 1 - table2.IntCol 2, 1)
于 2012-04-20T20:01:24.280 回答