如果我有一个双精度数(234.004223),等等,我想把它四舍五入到C#中的x个有效数字。
到目前为止,我只能找到四舍五入到小数点后x位的方法,但如果数字中有任何0,这只会消除精度。
例如,0.086到小数点后一位变为0.1,但我希望它保持在0.08。
发布于 2008-12-17 13:01:38
该框架没有内置的函数来舍入(或截断,如您的示例)到许多有效数字。不过,一种方法是缩放数字,使第一个有效数字紧跟在小数点之后,四舍五入(或截断),然后缩小。下面的代码应该可以做到这一点:
static double RoundToSignificantDigits(this double d, int digits){
if(d == 0)
return 0;
double scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(d))) + 1);
return scale * Math.Round(d / scale, digits);
}如果您真的想要截断,那么您需要:
static double TruncateToSignificantDigits(this double d, int digits){
if(d == 0)
return 0;
double scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(d))) + 1 - digits);
return scale * Math.Truncate(d / scale);
}发布于 2009-12-18 06:56:12
几个月来,我一直在使用pDaddy的sigfig函数,发现其中有一个bug。您不能取负数的对数,因此如果d为负数,则结果为NaN。
下面的代码更正了这个错误:
public static double SetSigFigs(double d, int digits)
{
if(d == 0)
return 0;
decimal scale = (decimal)Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(d))) + 1);
return (double) (scale * Math.Round((decimal)d / scale, digits));
}发布于 2008-12-17 12:27:18
在我看来,你根本不想四舍五入到小数点后的x位--你想要四舍五入到x个有效数字。因此,在您的示例中,您希望将0.086四舍五入到一个有效数字,而不是一个小数位。
现在,由于存储双精度数的方式,使用双精度和四舍五入到有效数字的数量在一开始就有问题。例如,您可以将0.12舍入到接近0.1的值,但是0.1不能精确地表示为双精度。您确定实际上不应该使用小数吗?或者,这实际上是为了显示目的吗?如果是为了显示目的,我怀疑您实际上应该将双精度值直接转换为具有相关有效位数的字符串。
如果你能回答这些问题,我可以试着想出一些合适的代码。尽管听起来很糟糕,但通过将数字转换为“完整”字符串,然后找到第一个有效数字(然后在此之后采取适当的舍入操作),将其转换为一个字符串可能是最好的方法。
https://stackoverflow.com/questions/374316
复制相似问题