Мне было интересно, возможно ли это выше. Например:
Math.Sqrt(myVariableHere);
При просмотре перегрузки требуется двойной параметр, поэтому я не уверен, есть ли другой способ реплицировать его с десятичными типами данных.
Мне было интересно, возможно ли это выше. Например:
Math.Sqrt(myVariableHere);
При просмотре перегрузки требуется двойной параметр, поэтому я не уверен, есть ли другой способ реплицировать его с десятичными типами данных.
В большинстве случаев, связанных с decimal
(валютой и т.д.), нецелесообразно использовать root; и корень не будет иметь ничего подобного ожидаемой точности, которую можно ожидать от decimal
. Вы можете, конечно, заставить его кастинг (при условии, что мы не имеем дело с крайними концами диапазона decimal
):
decimal root = (decimal)Math.Sqrt((double)myVariableHere);
что заставляет вас хотя бы признать неотъемлемые проблемы округления.
Я не понимаю, почему все ответы на этот вопрос одинаковы.
Существует несколько способов вычисления квадратного корня из числа. Один из них был предложен Исааком Ньютоном. Я напишу только одну из простейших реализаций этого метода. Я использую его для повышения точности двойного квадратного корня.
// x - a number, from which we need to calculate the square root
// epsilon - an accuracy of calculation of the root from our number.
// The result of the calculations will differ from an actual value
// of the root on less than epslion.
public static decimal Sqrt(decimal x, decimal epsilon = 0.0M)
{
if (x < 0) throw new OverflowException("Cannot calculate square root from a negative number");
decimal current = (decimal)Math.Sqrt((double)x), previous;
do
{
previous = current;
if (previous == 0.0M) return 0;
current = (previous + x / previous) / 2;
}
while (Math.Abs(previous - current) > epsilon);
return current;
}
О скорости: в худшем случае (epsilon = 0 и число decimal.MaxValue) цикл повторяется меньше трех раз.
Если вы хотите узнать больше, прочитайте this (Хакерский восторг от Генри С. Уоррена-младшего)
Я просто наткнулся на этот вопрос, и я бы предложил другой алгоритм, чем тот, который предложил Сленик. Это основано на вавилонском методе .
public static decimal Sqrt(decimal x, decimal? guess = null)
{
var ourGuess = guess.GetValueOrDefault(x / 2m);
var result = x / ourGuess;
var average = (ourGuess + result) / 2m;
if (average == ourGuess) // This checks for the maximum precision possible with a decimal.
return average;
else
return Sqrt(x, average);
}
Это не требует использования существующей функции Sqrt
и, таким образом, позволяет избежать преобразования в double
и обратно с сопровождающей потерей точности.
Простой: добавьте decimal
в double
и вызовите функцию, получите результат и отбросьте его обратно в decimal
. Вероятно, это будет быстрее, чем любая функция sqrt
, которую вы могли бы сделать самостоятельно, и сэкономить много усилий.
Math.Sqrt((double)myVariableHere);
Вернет вам двойник, который квадратный корень вашего decimal
myVariableHere
.