Несоответствие не имеет ничего общего с точностью как таковой, оно больше связано с тем, как работает представление с плавающей запятой.Например, если вы напишите это:
for (float f = 0.0f; f != 1.0f; f+=0.1f)
{
Console.WriteLine(f);
}
Он никогда не завершится.Потому что 0.1 не имеет точного представления в двоичной форме.(https://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/). Я также рекомендую прочитать (https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)
). Возвращаясь к проблеме, в вашем коде вы получаете радиус, используя это:
dimension / (2 * Math.PI); //passed in dimension is the Circumference, returns radius
Изатем в своем тесте вы утверждаете, что:
circumference - 2 * Math.PI * circle.Radius <= 0
Деление, а затем умножение на одно и то же число с плавающей запятой не гарантируют, что в результате вы получите исходное число с плавающей запятой.
Таким образомв целом это плохая идея утверждать это. Наиболее распространенный способ проверки "почти равенства" - это проверка равенства "в определенных пределах". В вашем случае все, что вам нужно сделать, это определить достаточно маленький эпсилон, который вы считаете "«приемлемо», больше или равно double.Epsilon в ваших тестах.
var epsilon = double.Epsilon;
Assert.IsTrue(
Math.Abs(circumference - circle.Circumference) <= epsilon //circumference
&& Math.Abs(circumference - 2 * Math.PI * circle.Radius) <= epsilon //radius
&& Math.Abs(circumference - Math.PI * circle.Diameter) <= epsilon //diameter
&& Math.Abs(Math.Pow(circumference / (2 * Math.PI), 2) * Math.PI - circle.Area) <= epsilon //area
&& string.IsNullOrEmpty(circle.ShapeException));
Если вместо этого вам нужно гарантировать точность, одним из вариантов является переключение на тип с плавающей запятой, например десятичный, но ожидайте производительностьудар.