我需要将一个数字截断为2位小数,这基本上意味着 砍掉额外的数字。
例如:
2.919 -> 2.91
2.91111 -> 2.91
为什么呢?这是SQL服务器在存储多个a时所做的事情 特别精确。例如,如果列是十进制(8,2),并且您尝试 插入/更新9.1234的数字,3和4将被切断。
我需要在c#代码中做同样的事情。
我能想到的唯一可行方法是:
使用stringformatter仅“打印”出来 两位小数,然后将其转换为小数, 例如:
decimal tooManyDigits = 2.1345
decimal ShorterDigits = Convert.ToDecimal(tooManyDigits.ToString("0.##"));
// ShorterDigits is now 2.13
我对此并不满意,因为它涉及一个to-string然后 另一个字符串到十进制转换似乎有点疯狂。
使用Math.Truncate(只接受整数),所以我 可以将它乘以100,截断它,然后除以100.例如:
decimal tooLongDecimal = 2.1235;
tooLongDecimal = Math.Truncate(tooLongDecimal * 100) / 100;
我对此也不满意,因为如果tooLongDecimal是0, 我会得到0分之差。
肯定有更好的+更简单的方法!有什么建议吗?
答案 0 :(得分:5)
你自己回答了这个问题;你似乎只是误解了零除的意思。这样做的正确方法是乘法,截断,然后分开,如下所示:
decimal TruncateTo100ths(decimal d)
{
return Math.Truncate(d* 100) / 100;
}
TruncateTo100ths(0m); // 0
TruncateTo100ths(2.919m); // 2.91
TruncateTo100ths(2.91111m); // 2.91
TruncateTo100ths(2.1345m); // 2.13
这里没有除零,只有除以100,这是完全安全的。
答案 1 :(得分:3)
以前提供的数学解决方案很容易因大量数字和/或大量小数位而溢出。请考虑以下扩展名:
[System.Runtime.CompilerServices.Extension()]
public static decimal TruncateDecimal(decimal d, int decimals)
{
if (decimals < 0)
throw new ArgumentOutOfRangeException("decimals", "Value must be in range 0-28.");
else if (decimals > 28)
throw new ArgumentOutOfRangeException("decimals", "Value must be in range 0-28.");
else if (decimals = 0)
return Math.Truncate(d);
else {
decimal integerPart = Math.Truncate(d);
decimal scalingFactor = d - integerPart;
decimal multiplier = Math.Pow(10, decimals);
scalingFactor = Math.Truncate(scalingFactor * multiplier) / multiplier;
return integerPart + scalingFactor;
}
}
用法:
decimal value = 18446744073709551615.262626263m;
value = value.TruncateDecimal(6);
答案 2 :(得分:1)
我同意p.s.w.g.我有类似的要求,这是我的经验和截断的更广义的功能。
http://snathani.blogspot.com/2014/05/truncating-number-to-specificnumber-of.html
public static decimal Truncate(decimal value, int decimals)
{
decimal factor = (decimal)Math.Pow(10, decimals);
decimal result = Math.Truncate(factor * value) / factor;
return result;
}
答案 3 :(得分:0)
使用decimal.ToString('0.##')
也强加四舍五入:
1.119M.ToString("0.##") // -> 1.12
(是的,可能应该是一个评论,但这样很难格式化。)
答案 4 :(得分:0)
public static decimal Rounding(decimal val, int precision)
{
decimal res = Trancating(val, precision + 1);
return Math.Round(res, precision, MidpointRounding.AwayFromZero);
}
public static decimal Trancating(decimal val,int precision)
{
if (val.ToString().Contains("."))
{
string valstr = val.ToString();
string[] valArr = valstr.Split('.');
if(valArr[1].Length < precision)
{
int NoOfZeroNeedToAdd = precision - valArr[1].Length;
for (int i = 1; i <= NoOfZeroNeedToAdd; i++)
{
valstr = string.Concat(valstr, "0");
}
}
if(valArr[1].Length > precision)
{
valstr = valArr[0] +"."+ valArr[1].Substring(0, precision);
}
return Convert.ToDecimal(valstr);
}
else
{
string valstr=val.ToString();
for(int i = 0; i <= precision; i++)
{
if (i == 1)
valstr = string.Concat(valstr, ".0");
if(i>1)
valstr = string.Concat(valstr, "0");
}
return Convert.ToDecimal(valstr);
}
}