我有一个我不能改变的情况:一个数据库表(表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)
我想能够找出表A中的数量*单位是否超过3个小数(第1行将失败,第2行将通过):
if (CountDecimalPlaces(tableA.Qty * tableA.Unit) > 3) { return false; } tableB.TotalQty = tableA.Qty * tableA.Unit;
我将如何实现CountDecimalPlaces(十进制值){}函数?
解决方法
它适用于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)); }
对于一个真正的通用解决方案,您需要在其部分中“解构”十进制值 – 有关更多信息,请查看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)); }