在我的C#程序中,我从某些计算中获得double
,其值类似于0,13999
或0,0079996
,但此值必须呈现给人类,以便更好地显示分别为0,14
或0,008
。
所以我需要对值进行舍入,但不知道哪个精度 - 我只需要“丢掉那些噪音数字”。
我怎么能在我的代码中这样做?
澄清 - 我需要在编译时将double
值四舍五入到 unknown 的精度 - 这需要在运行时确定。什么是一个很好的启发式来实现这一目标?
答案 0 :(得分:1)
private double PrettyRound(double inp)
{
string d = inp.ToString();
d = d.Remove(0,d.IndexOf(',') + 1);
int decRound = 1;
bool onStartZeroes = true;
for (int c = 1; c < d.Length; c++ )
{
if (!onStartZeroes && d[c] == d[c - 1])
break;
else
decRound++;
if (d[c] != '0')
onStartZeroes = false;
}
inp = Math.Round(inp, decRound);
return inp;
}
测试:
double d1 = 0.13999; //no zeroes
double d2 = 0.0079996; //zeroes
double d3 = 0.00700956; //zeroes within decimal
Response.Write(d1 + "<br/>" + d2 + "<br/>" + d3 + "<br/><br/>");
d1 = PrettyRound(d1);
d2 = PrettyRound(d2);
d3 = PrettyRound(d3);
Response.Write(d1 + "<br/>" + d2 + "<br/>" + d3 +"<br/><br/>");
打印:
0,13999
0,0079996
0,00700956
0,14
0008
0007
在你的例子中写下你的数字。
答案 1 :(得分:1)
您似乎想要输出一个与输入值差别不大的值,因此请尝试增加位数,直到达到给定的错误:
static double Round(double input, double errorDesired)
{
if (input == 0.0)
return 0.0;
for (int decimals = 0; decimals < 17; ++decimals)
{
var output = Math.Round(input, decimals);
var errorAchieved = Math.Abs((output - input) / input);
if (errorAchieved <= errorDesired)
return output;
}
return input;
}
}
static void Main(string[] args)
{
foreach (var input in new[] { 0.13999, 0.0079996, 0.12345 })
{
Console.WriteLine("{0} -> {1} (.1%)", input, Round(input, 0.001));
Console.WriteLine("{0} -> {1} (1%)", input, Round(input, 0.01));
Console.WriteLine("{0} -> {1} (10%)", input, Round(input, 0.1));
}
}
答案 2 :(得分:0)
您可以在不转换为字符串的情况下执行此操作。这就是我快速创建的:
private static double RoundDecimal(double number)
{
double temp2 = number;
int temp, counter = 0;
do
{
temp2 = 10 * temp2;
temp = (int)temp2;
counter++;
} while (temp < 1);
return Math.Round(number, counter < 2 ? 2 : counter);
}
或
private static double RoundDecimal(double number)
{
int counter = 0;
if (number > 0) {
counter = Math.Abs((int) Math.Log10(number)) + 1;
return Math.Round(arv, counter < 2 ? 2 : counter);
}
答案 3 :(得分:0)
我可以想到一个解决方案虽然效率不高......
我的假设是,当一个数字处于“最佳”人类可读格式时,如果额外的数字与舍入方式没有区别,你可以判断它是什么。
例如在0,13999的示例中将其四舍五入到不同的小数位数给出:
0
0.1
0.14
0.14
0.14
0.13999
我建议你可以循环检测那个稳定的补丁并切断它。
这种方法似乎是这样做的:
public double CustomRound(double d)
{
double currentRound = 0;
int stability = 0;
int roundLevel = 0;
while (stability < 3)
{
roundLevel++;
double current = Math.Round(d, roundLevel);
if (current == currentRound)
{
stability++;
}
else
{
stability = 1;
currentRound=current;
}
}
return Math.Round(d, roundLevel);
}
此代码可能是可清除的,但它可以完成工作,并且是一个充分的概念证明。 :)
我应该强调的是,初始假设(舍入时没有变化)是我们正在考虑的标准,这意味着像0.3333333333这样的东西根本不会被四舍五入。根据给出的例子,我无法说明这是否正确但我认为这是一个双重问题,问题是“正确”值和值为双重的非常小的变化。
答案 4 :(得分:0)
继承我尝试的内容:
public decimal myRounding(decimal number)
{
double log10 = Math.Log10((double) number);
int precision = (int)(log10 >= 0 ? 0 : Math.Abs(log10)) + (number < 0.01m ? 1 : 2);
return Math.Round(number, precision);
}
试验:
Console.WriteLine(myRounding(0.0000019999m)); //0.000002
Console.WriteLine(myRounding(0.0003019999m)); //0.0003
Console.WriteLine(myRounding(2.56777777m)); //2.57
Console.WriteLine(myRounding(0.13999m)); //0.14
Console.WriteLine(myRounding(0.0079996m)); //0.008
答案 5 :(得分:0)
在给出另一个想法之后,我做了以下操作,看起来它到目前为止我做了什么。
我迭代了位数并比较Round( value, number )
和Round( value, number + 1 )
。一旦它们相等(当然不是==
- 我将差异与较小的数字进行比较),那么number
是我正在寻找的数字位数。
答案 6 :(得分:-1)
Double.ToString()
可以采用字符串格式作为参数。这将显示您需要的任意数量的字符,四舍五入到小数位。 E.G:
double Value = 1054.32179;
MessageBox.Show(Value.ToString("0.000"));
将显示“1054.322”。
答案 7 :(得分:-4)
您可以在Math.Round函数中使用no数字
Double doubleValue = 4.052102;
Math.Round(doubleValue, 2);
这将返回4.05作为您的要求答案。
这是经过测试的代码,你可以解释一下我的错误。所以我需要改变。