N-й корень малого числа возвращает неожиданный результат в C # - PullRequest
5 голосов
/ 10 октября 2009

Когда я пытаюсь получить N-й корень небольшого числа с помощью C #, я получаю неправильное число.

Например, когда я пытаюсь получить третий корень 1.07, я получаю 1, что явно не соответствует действительности.

Вот точный код, который я использую для получения третьего корня.

MessageBox.Show(Math.Pow(1.07,(1/3)).toString());

Как мне решить эту проблему?

Я бы предположил, что это арифметическая проблема с плавающей запятой, но я не знаю, как ее решить.

Ответы [ 4 ]

13 голосов
/ 10 октября 2009

C # обрабатывает 1 и 3 как целые числа, вам нужно сделать следующее:

Math.Pow(1.07,(1d/3d))

или

Math.Pow(1.07,(1.0/3.0))

Это на самом деле интересно, потому что неявное расширяющее преобразование заставляет вас ошибиться.

9 голосов
/ 10 октября 2009

Я почти уверен, что "точный код", который вы даете, не компилируется.

MessageBox.Show(Math.Pow(1.07,(1/3).toString()));

Вызов toString находится на неправильном уровне вложенности, должен быть ToString, а (1/3) - целочисленное деление, что, вероятно, является реальной проблемой, с которой вы столкнулись. (1/3) равно 0, а все до нулевой степени равно 1. Вам нужно использовать (1.0 / 3.0) или (1d / 3d) или ...

3 голосов
/ 10 октября 2009

Перво-наперво: если это именно тот код, который вы используете, вероятно, что-то не так с вашим компилятором: -)

MessageBox.Show(Math.Pow(1.07,(1/3).toString()));

сначала оценит (1/3) .toString (), затем попытается поднять 1,07 до степени этой строки.

Я думаю, вы имеете в виду:

MessageBox.Show(Math.Pow(1.07,(1/3)).ToString());

Что касается проблемы, то (1/3) рассматривается как целочисленное деление, возвращающее 0, а n 0 равно 1 для всех значений n.

Вам нужно привести его к делению с плавающей запятой, например, 1.0/3.0.

1 голос
/ 21 августа 2013

Это может помочь в случае, если у вас есть реальная проблема точности n-го корня, но мой опыт показывает, что встроенный Math.Pow (double, int) более точен:

    private static decimal NthRoot(decimal baseValue, int N)
    {
        if (N == 1)
            return baseValue;
        decimal deltaX;
        decimal x = 1M;
        do
        {
            deltaX = (baseValue / Pow(x, N - 1) - x) / N;
            x = x + deltaX;
        } while (Math.Abs(deltaX) > 0);
        return x;
    }

    private static decimal Pow(decimal a, int b)
    {
        if (b == 0) return 1;
        if (a == 0) return 0;
        if (b == 1) return a;
        if (b % 2 == 0)
            return Pow(a * a, b / 2);
        else if (b % 2 == 1)
            return a * Pow(a * a, b / 2);
        return 0;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...