#c_sharp #net #double
Доброго времени суток! Возник следующий вопрос: к примеру, у нас есть переменная типа double и некоторая точность (переменная precition), которая будет определять количество интересующих нас знаков после запятой: double x = 9.3813020199999; double precition = 0.001; Зная вышеперечисленные данные, нам нужно получить точное число 9.381 (и без лишних нулей в конце). Есть ли способ это осуществить? UPD Мне необходимо протестировать метод Sqrt (код ниже) и я не знаю, как правильно написать тест для NUnit, если метод возвращает число double. Ведь у нас должно быть expected-значение, которое сравнивается с возвращаемым значением метода. public static double Sqrt(double x, int n, double precition) { if (x < 0 && n % 2 == 0) throw new ArgumentException(); double result = x / n; double previousResult; do { previousResult = result; result = ((double)1 / n) * ((n - 1) * previousResult + (x / Sqr(previousResult, n - 1))); } while (Math.Abs(result - previousResult) > precition); return result; } Пока мой тестирующий метод, написанный с помощью NUnit, выглядит так: [TestFixture] public class NewtonSqrtTests { [TestCase(4, 2, 0.001, ExpectedResult = 2.000)] [TestCase(27, 3, 0.0001, ExpectedResult = 3.0000)] [TestCase(88, 2, 0.001, ExpectedResult = 9.380)] [TestCase(81, 2, 0.001, ExpectedResult = 9.000)] public double Sqrt_PositiveTest(double x, int n, double precition) { return NewtonSqrt.Sqrt(x, n, precition); } }
Ответы
Ответ 1
Если говорить о десятичных знаках, то оставаться в рамках типа double бессмысленно: в нём вы не можете выразить вашу требуемую точность точно. Например, потому, что в типе double нельзя точно выразить ни число 0.001, ни число 9.381. (иллюстрация, связанный ответ) Вам нужно перейти к типу decimal, который специально для этого предназначен. double x = 9.3813020199999; decimal precision = 0.001m; decimal result = Math.Round((decimal)x / precision) * precision; // 9.381 Если количество десятичных знаков известно в виде числа, можно проще: double x = 9.3813020199999; decimal result = Math.Round((decimal)x, 3); // 9.381 Обновление: Если оставаться в рамках типа double, вы не можете их сравнивать: равенство теоретически одинаковых чисел типа double, вычисленных разными путями — практически невероятное событие из-за ошибок округления. В таких случаях используется примерное равенство с точностью до epsilon. Например, в NUnit есть для таких целей специальные функции: Values of type float and double are normally compared using a tolerance specified by the Within modifier.
Комментариев нет:
Отправить комментарий