Вопрос

Странные вещи случаются, когда я пытаюсь найти кубический корень числа.

Следующий код возвращает меня undefined. В CMD: -1. # Ind

cout<<pow(( double )(20.0*(-3.2) + 30.0),( double )1/3)

Хотя этот этот работает отлично. В CMD: 4.93242414866094

cout<<pow(( double )(20.0*4.5 + 30.0),( double )1/3)

Из математического способа он должен работать, так как мы можем иметь корень куба от отрицательного числа. POW от Visual C ++ 2010 Math.h Библиотека. Есть идеи?

Это было полезно?

Решение

pow(x, y) от <cmath> Не работает, если X отрицательна, а Y не интегральна.

Это ограничение std::pow, как задокументировано в стандарте C и на CPPreference:

Обработка ошибок

  • Ошибки сообщаются, как указано в Math_errandling
  • Если база имеет конечное и отрицательное, и EXP - это конечное и не целое число, возникает ошибка домена, и может произойти ошибка диапазона.
  • Если база равно нулю, и EXP равен нулю, может возникнуть ошибка домена.
  • Если база равно нулю, и EXP отрицателен, может произойти ошибка домена или ошибка полюса.

Вокруг этого ограничения есть пара путей:

  • Cube-robing такой же, как принять что-то до 1/3 мощности, чтобы вы могли сделать std::pow(x, 1/3.).

  • В C ++ 11 вы можете использовать std::cbrt. Отказ C ++ 11 представила функции квадратного корня и Cube-root, но без общего значения N-Th Root-функции преодолевают ограничения std::pow.

Другие советы

Сила 1/3 это особый случай. В общем, неинтегральные полномочия негативных чисел являются сложными. Было бы не было бы практично для принятия специальных случаев, таких как целочисленные корни, и, кроме того, 1/3 Как двойной не ровно 1/3!

Я не знаю о Visual C ++ POW, но страница моего человека говорит по ошибкам:

EDOM Аргумент x негативно и y не является неотъемлемой стоимостью. Это приведет к сложному номеру.

Вам придется использовать более специализированные корневые функции Cube, если вы хотите, чтобы кубические корни негативных чисел - или вырезают углы и возьмите абсолютное значение, а затем взять кубик Coot, затем умножьте знак обратно.

Обратите внимание, что в зависимости от контекста, отрицательное число x к тому 1/3 Мощность не обязательно является отрицательным кубом корень, которые вы ожидаете. Это может быть так же легко быть первым сложным корнем, x^(1/3) * e^(pi*i/3). Отказ Это конвенция Mathematica использует; Также разумно просто сказать, что это не определено.

Пока (-1) ^ 3 = -1, вы не можете просто принять рациональную силу отрицательного числа и ожидать реального ответа. Это потому, что есть и другие решения для этого рационального показателя, которые воображаются в природе.
http://www.wolframalpha.com/input/?i=x^(1/3),+x+from+-5+TO+0.

Аналогично, сюжет x ^ x. Для x = -1/3 это должно иметь решение. Однако эта функция считается неопределенной в R для X <0.

Поэтому не ожидайте, что математика.

Угадай, что вы должны взять негативную и положить его впоследствии. Вы можете иметь обертку сделать это для вас, если вы действительно хотите.

function yourPow(double x, double y)
{
    if (x < 0)
        return -1.0 * pow(-1.0*x, y);
    else
        return pow(x, y);
}

Не бросайтесь double используя (double), Вместо этого используйте двойную числовую постоянную:

double thingToCubeRoot = -20.*3.2+30;
cout<< thingToCubeRoot/fabs(thingToCubeRoot) * pow( fabs(thingToCubeRoot), 1./3. );

Должен сделать трюк!

Также: не включать <math.h> в проектах C ++, но использовать <cmath> вместо.

Альтернативно, использовать pow из <complex> Заголовок по причинам, указанным Буддабротом

pow( x, y ) такой же, как (то есть эквивалентный) exp( y * log( x ) )

Если журнал (X) недействителен, то POW (X, Y) также.

Точно так же вы не можете выполнять 0 до мощности чего-либо, хотя математически это должно быть 0.

C ++ 11 имеет cbrt Функция (см. Например http://en.cppreference.com/w/cpp/numeric/math/cbrt.) так что вы можете написать что-то вроде

#include <iostream>
#include <cmath>

int main(int argc, char* argv[])
{
   const double arg = 20.0*(-3.2) + 30.0;
   std::cout << cbrt(arg) << "\n";
   std::cout << cbrt(-arg) << "\n";
   return 0;
}

У меня нет доступа к стандарту C ++, поэтому я не знаю, как обрабатывается негативный аргумент ... тест на IDeOne http://ideone.com/bflxys. Похоже, подтверждает, что C ++ (GCC-4.8.1) расширяет корню куба с этим правилом cbrt(x)=-cbrt(-x) когда x<0; Для этого расширения вы можете увидеть http://mathworld.wolfram.com/cuberoot.html.

Я искал Cubit Coot и нашел эту нить, и это происходит для меня, что следующий код может работать:

#include <cmath>
using namespace std;

function double nth-root(double x, double n){
    if (!(n%2) || x<0){
        throw FAILEXCEPTION(); // even root from negative is fail
    }

    bool sign = (x >= 0);

    x = exp(log(abs(x))/n);

    return sign ? x : -x;
}

Я думаю, что вы не должны путать экспоненцию с NTH-ROOT of of of. Увидеть старость Википедия

Потому что 1/3 всегда будет возвращаться 0, так как он будет рассматриваться как целое число ... попробуйте с 1.0 / 3.0 ... Это то, что я думаю, но попробую и реализую ... и не забудьте объявить переменные, содержащие 1,0 и 3.0 Как двойной ...

Вот небольшая функция, которую я постучал.

#define uniform() (rand()/(1.0 + RAND_MAX))

double CBRT(double Z)
{
    double guess = Z;
    double x, dx;
    int loopbreaker;

retry:
    x = guess * guess * guess;
    loopbreaker = 0;
    while (fabs(x - Z) > FLT_EPSILON)
    {
        dx = 3 * guess*guess;
        loopbreaker++;
        if (fabs(dx) < DBL_EPSILON || loopbreaker > 53)
        {
            guess += uniform() * 2 - 1.0;
            goto retry;
        }
        guess -= (x - Z) / dx;
        x = guess*guess*guess;
    }

    return guess;
}

Он использует Ньютон-Рафсон, чтобы найти кубический корень.

Когда-нибудь Ньютон -РАпринсон застрял, если root очень близко к 0, то производное может получить большое, и он может колебаться. Так что я зажал и заставил его перезапустить, если это произойдет. Если вам нужно больше точности, вы можете изменить FLT_EPSILONS.

Если у вас когда-либо не было математической библиотеки, вы можете использовать этот способ для вычисления кубического корня:

кубический корень

double curt(double x) {
  if (x == 0) {
    // would otherwise return something like 4.257959840008151e-109
    return 0;
  }
  double b = 1; // use any value except 0
  double last_b_1 = 0;
  double last_b_2 = 0;
  while (last_b_1 != b && last_b_2 != b) {
    last_b_1 = b;
    // use (2 * b + x / b / b) / 3 for small numbers, as suggested by  willywonka_dailyblah
    b = (b + x / b / b) / 2;
    last_b_2 = b;
    // use (2 * b + x / b / b) / 3 for small numbers, as suggested by  willywonka_dailyblah
    b = (b + x / b / b) / 2;
  }
  return b;
}

Это происходит от sqrt алгоритм ниже. Идея в том, что b а также x / b / b больше и меньше от кубического корня x. Отказ Итак, среднее значение обеих ближе к кубическому корню x.

Квадратный корень и кубический корень (в Python)

def sqrt_2(a):
    if a == 0:
        return 0
    b = 1
    last_b = 0
    while last_b != b:
        last_b = b
        b = (b + a / b) / 2
    return b

def curt_2(a):
    if a == 0:
        return 0
    b = a
    last_b_1 = 0;
    last_b_2 = 0;
    while (last_b_1 != b and last_b_2 != b):
        last_b_1 = b;
        b = (b + a / b / b) / 2;
        last_b_2 = b;
        b = (b + a / b / b) / 2;
    return b

В отличие от квадратного корня, last_b_1 а также last_b_2 требуются в кубическом корне, потому что B мерцают. Вы можете изменить эти алгоритмы для вычисления четвертого корня, пятого корня и так далее.

Благодаря моим учителю математики Херр Бреннер в 11-м классе, который сказал мне этот алгоритм для sqrt.

Представление

Я проверил его на Arduino с часовой частотой 16 МГц:

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top