如何在SQL中存储为十进制(4,1)之前验证/验证浮点数?

时间:2010-06-10 19:03:51

标签: c# sql floating-point

我已经在SQL中将一列定义为decimal(4,1), null,这意味着我存储了四个数字,其中一个数字可以在小数点的右边。

源数据应始终在0到999.9的范围内,但由于我无法控制的错误,我收到了数字-38591844.0。显然,这不会存储在SQL中并且会出现错误“算术溢出错误将实数转换为数据类型数字。”

如果值超出范围,我想存储null。

验证C#中的值是否超出上面定义的SQL列的边界的最佳方法是什么?

虽然这似乎是最简单的方法......

private bool Validate41Float(float f)
{
    if (f >= 0 && f <= 999.9) return true;
    else return false;
}

我担心如果由于某种原因我得到了价值:10.12345。在这种情况下,我只想存储10.1,但额外的精度会导致相同的SQL错误吗?

3 个答案:

答案 0 :(得分:2)

我知道您可以向SQL Server提交10.12345,它只会转到10.1并且不会抱怨。我肯定不了解其他数据库供应商,但我认为它们的工作原理相同。

您也可以拥有负值。为了清楚你在做什么,你可能想要明确地舍入然后测试你的逻辑:

private bool Validate41Float(float f)
{
    float rounded = (float)Math.Round(f, 1);
    if (rounded > -1000 && rounded < 1000) return true;
    else return false;
}

答案 1 :(得分:1)

---在评论后编辑澄清了问题---

大多数数据库都会对数字进行四舍五入以适应格式。我不确定这是SQL标准还是数据库供应商的常见做法。

如果数字太大而无法存储在数据库中(如123456.7),大多数数据库都会引发错误,该数字无法满足精度要求。该领域。

---原帖如下---

浮点数不代表确切的数据值,它们只表示可以正确表示为基数2的分数之和的数据值。

例如1.75将完全可以表示,因为它是1 + 1/2 + 1/4。像1和1/3这样的数字不能准确表示,因为1/2 ^ n形式的分数之和不能代表1/3。

考虑到这一点,如果这确实是一个关键问题,您需要执行以下操作之一:

  1. 将结果舍入(或修剪)到最接近.1,.2,.3等的东西。这仍然会有问题,但它总比没有好。
  2. 将数字表示为整数,只需“记住”整数是十分之一,而不是一数。
  3. 银行应用程序通常使用第二种技术,以消除一分钱和舍入错误的可能性。

答案 2 :(得分:0)

这是我实施的扩展方法,基于Tim Coker的回答:

    private static float? ValidateDecimal41(this float? f)
    {
        if (!f.HasValue) return f;
        float rounded = (float)Math.Round((float)f, 1);
        if (rounded >= 0 && rounded <= 999.9) return rounded;
        else return null;
    }

这让我:

  • 继续接受并存储空值,
  • 将任何被视为超出相关值范围的值转换为null,并
  • 舍入到一个小数点以避免SQL中潜在的精度错误