我有一种情况我无法改变:一个数据库表(表A)接受6个小数位,而另一个表(表B)中的相关列只有3个小数位.
我需要从A复制到B,但如果A的小数位数超过3,则额外数据将丢失.我无法更改表定义,但我可以添加一个解决方法.所以我试图找出如何检查小数是否超过3位小数?
例如
Table A
Id, Qty, Unit(=6dp)
1, 1, 0.00025
2, 4000, 0.00025
Table B
Id, TotalQty(=3dp)
Run Code Online (Sandbox Code Playgroud)
我希望能够找出表A中的Qty*Unit是否超过3位小数(第1行会失败,第2行会通过):
if (CountDecimalPlaces(tableA.Qty * tableA.Unit) > 3)
{
return false;
}
tableB.TotalQty = tableA.Qty * tableA.Unit;
Run Code Online (Sandbox Code Playgroud)
我该如何实现这个CountDecimalPlaces(decimal value) {}功能?
Rod*_*257 49
您可以将舍入到3位小数的数字值与原始值进行比较.
if (Decimal.Round(valueDecimal, 3) != valueDecimal)
{
//Too many decimals
}
Run Code Online (Sandbox Code Playgroud)
car*_*ira 14
这适用于3位小数,它可以适用于通用解决方案:
static bool LessThan3DecimalPlaces(decimal dec)
{
decimal value = dec * 1000;
return value == Math.Floor(value);
}
static void Test()
{
Console.WriteLine(LessThan3DecimalPlaces(1m * 0.00025m));
Console.WriteLine(LessThan3DecimalPlaces(4000m * 0.00025m));
}
Run Code Online (Sandbox Code Playgroud)
对于一个真正的通用解决方案,您需要"解构"其部分中的十进制值 - 请查看Decimal.GetBits以获取更多信息.
更新:这是一个通用解决方案的简单实现,适用于整数部分小于long的所有小数.MaxValue(对于trully泛型函数,你需要类似"大整数"的东西).
static decimal CountDecimalPlaces(decimal dec)
{
int[] bits = Decimal.GetBits(dec);
int exponent = bits[3] >> 16;
int result = exponent;
long lowDecimal = bits[0] | (bits[1] >> 8);
while ((lowDecimal % 10) == 0)
{
result--;
lowDecimal /= 10;
}
return result;
}
static void Foo()
{
Console.WriteLine(CountDecimalPlaces(1.6m));
Console.WriteLine(CountDecimalPlaces(1.600m));
Console.WriteLine(CountDecimalPlaces(decimal.MaxValue));
Console.WriteLine(CountDecimalPlaces(1m * 0.00025m));
Console.WriteLine(CountDecimalPlaces(4000m * 0.00025m));
}
Run Code Online (Sandbox Code Playgroud)
将小数点后 3 位的数字乘以 10 的 3 次方将得到一个没有小数位的数字。当模数为整数时% 1 == 0。所以我想出了这个......
bool hasMoreThanNDecimals(decimal d, int n)
{
return !(d * (decimal)Math.Pow(10, n) % 1 == 0);
}
Run Code Online (Sandbox Code Playgroud)
n当小于(不等于)小数位数时返回 true 。
这是一个非常简单的单行代码,用于获取小数位数:
decimal myDecimal = 1.000000021300010000001m;
byte decimals = (byte)((Decimal.GetBits(myDecimal)[3] >> 16) & 0x7F);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
36027 次 |
| 最近记录: |