我正在尝试验证c#中的小数是否适合db列十进制。 SqlDecimal对象允许您将精度和小数位以及小数位传递给构造函数。我知道列的大小,所以在我们编写数据之前,我检查每个输入,这样我就可以生成业务所需的输出。
在这种情况下,我们存储百分比,因此精度 13 且比例 10 。我有一个测试工具,我已经在下面浓缩成了针对SO的unti测试。此示例在SqlDecimal构造函数行上抛出了算术溢出错误:
[TestMethod]
public void TestDecimalFits()
{
decimal d = 10.3m;
SqlDecimal sqlDecimal = new SqlDecimal(13, 10, d >= 0, Decimal.GetBits(d));
Assert.AreEqual(d, sqlDecimal.Value);
}
有谁知道为什么会爆炸?
谢谢!
答案 0 :(得分:1)
Decimal.GetBits
的返回与SqlDecimal
的构造函数参数不兼容。
Decimal.GetBits
返回一个数组,表示十进制的确切结构,包括96位缩放的整数值和指数的8位(加1个符号位和27个未使用的位)。
您正在使用的SqlDecimal
constructor采用int
数组表示" 128位无符号整数,它提供新SqlDecimal的值。" - 不是该十进制值的代表。 scale
参数确定小数的实际值是什么。
因此,您实际上传递的值不同于构造函数所期望的值。 .NET十进制等效值10.3m是
0000000001100111-0000000000000000-0000000000000000-10000000000000000
其中1100111
是二进制等效值103,而1
是比例。
该二进制值的等价整数大于13位,这就是为什么在将它传递给SqlDecimal构造函数时会出现溢出的原因。
我不会玩bit-fiddling而只是使用原始decimal
值,让SQL将其转换为正确的精度并自动缩放。
我试图验证c#中的小数是否适合db列十进制。
嗯,适合DECIMAL(13,10)
的最大值是999.9999999999
,远远低于decimal
的最大值。所以不,你不能在DECIMAL(13,10)
SQL列中存储任何 C#十进制值。
(从技术上讲,我认为您可以通过降低精度来存储9999999999999
,但即使这样也远低于decimal
的最大值。
答案 1 :(得分:0)
我的猜测是Decimal.GetBits(d)
溢出了Int32返回类型。
尝试只做Int32 bits = Decimal.GetBits(d)
并查看它是否会抛出相同的错误。