如何围捕(没有上限)在C#:N.5达(+)无限
问题描述:
如问题,如何围捕中C#
与n.5
值(n
为整数):如何围捕(没有上限)在C#:N.5达(+)无限
1.5 -> 2
2.5 -> 3
-1.5 -> -1
-2.5 -> -2
1.4 -> 1
1.6 -> 2
-1.4 -> -1
-1.6 -> -2
我搜索但在C#
,Math.Round
只支持MidpointRounding.AwayFromZero
和MidpointRounding.ToEven
。也许程序员应该做把戏在正常的生活思想(不是银行业或学术思想......)中围绕一个数字?
也就是说预期的结果是在Javascript,价值N.5总是四舍五入到(+)无限 +∞
答
试试这个:)
[TestFixture]
public class TestClass
{
int NumberOfDecimalDigits(double d)
{
var text = Math.Abs(d).ToString();
int integerPlaces = text.IndexOf('.');
int decimalPlaces = text.Length - integerPlaces - 1;
return decimalPlaces;
}
double GetDelta(int numberOfDecimalDigits)
{
var deltaStringBuilder = new StringBuilder();
deltaStringBuilder.Append("1");
for (int i = 0; i < numberOfDecimalDigits; i++)
{
deltaStringBuilder.Append("0");
}
double delta = 1/double.Parse(deltaStringBuilder.ToString());
return delta;
}
double Round(double value, int digits)
{
if (value > 0)
{
return Math.Round(value, digits, MidpointRounding.AwayFromZero);
}
if (value < 0)
{
var numberOfDecimalDigits = NumberOfDecimalDigits(value);
double delta = GetDelta(numberOfDecimalDigits);
return Math.Round(value + delta, digits, MidpointRounding.AwayFromZero);
}
return value;
}
double Round(double value)
{
if (value > 0)
{
return Math.Round(value, MidpointRounding.AwayFromZero);
}
if (value < 0)
{
var numberOfDecimalDigits = NumberOfDecimalDigits(value);
double delta = GetDelta(numberOfDecimalDigits);
return Math.Round(value + delta, MidpointRounding.AwayFromZero);
}
return value;
}
[Test]
public void TestMethod()
{
Assert.AreEqual(Round(1), 1);
Assert.AreEqual(Round(1.9), 2);
Assert.AreEqual(Round(1.5), 2);
Assert.AreEqual(Round(2.5), 3);
Assert.AreEqual(Round(-1), -1);
Assert.AreEqual(Round(-2.9), -3);
Assert.AreEqual(Round(-1.5), -1);
Assert.AreEqual(Round(-2.5), -2);
Assert.AreEqual(Round(1.4), 1);
Assert.AreEqual(Round(1.6), 2);
Assert.AreEqual(Round(-1.4), -1);
Assert.AreEqual(Round(-1.6), -2);
Assert.AreEqual(Round(-1.55), -2);
Assert.AreEqual(Round(-1.6666), -2);
Assert.AreEqual(Round(-0.9999999), -1);
Assert.AreEqual(Round(-0.001), 0);
Assert.AreEqual(Round(2.35, 1), 2.4);
Assert.AreEqual(Round(-2.35, 1), -2.3);
}
+0
这个'-1.55'为'-1'。 – Ryan
+0
@Ryan让检查更新 –
答
下面是其通过一个版本所有测试用例。
static void Main(string[] args)
{
Round(double.Epsilon, 0);
Round(0-double.Epsilon, 0);
Round(1 + double.Epsilon, 1);
Round(1 - double.Epsilon, 1);
Round(1.5, 2);
Round(2.5, 3);
Round(-1.5, -1);
Round(-2.5, -2);
Round(1.4, 1);
Round(1.6, 2);
Round(-1.4, -1);
Round(-1.6, -2);
}
private static void Round(double v1, int v2)
{
var equal = (MyRound(v1) == v2) ? "==" : "!=";
Console.WriteLine($"Math.Round({v1}) {equal} {v2}, it's {MyRound(v1)}");
}
private static double MyRound(double v1)
{
return (v1 < 0)
? 0 - Math.Round(Math.Abs(v1)-0.1)
: Math.Round(v1, MidpointRounding.AwayFromZero);
}
输出:
Math.Round(4.94065645841247E-324) == 0, it's 0
Math.Round(-4.94065645841247E-324) == 0, it's 0
Math.Round(1) == 1, it's 1
Math.Round(1) == 1, it's 1
Math.Round(1.5) == 2, it's 2
Math.Round(2.5) == 3, it's 3
Math.Round(-1.5) == -1, it's -1
Math.Round(-2.5) == -2, it's -2
Math.Round(1.4) == 1, it's 1
Math.Round(1.6) == 2, it's 2
Math.Round(-1.4) == -1, it's -1
Math.Round(-1.6) == -2, it's -2
@AluanHaddad:尝试'Math.Round(-3.5)'。 (.NET甚至在默认情况下轮回)。 – Ryan
@AluanHaddad在C#中,默认舍入是** ToEven **。所以'-2.5 - > -2'和'-1.5 - > -2'也是如此。你可以尝试在http://rextester.com/ –
相关[SO](https://stackoverflow.com/questions/311696/why-does-net-use-bankers-rounding-as-default)和[数学.SE](https://mathematica.stackexchange.com/questions/2116/why-round-to-even-integers)。半决赛并不是真正的“正常生活”,这正是小学通常所教的内容。 – Martheen