Как использовать каретку «^» в C ++ для экспонирования

0

В настоящее время я переписываю код MATLAB в код C++. Чтобы иметь возможность поднять "a" до степени "b", просто набрав "a ^ b", моя жизнь станет намного проще, так как это то, что из исходного кода было написано в MATLAB.

Есть ли способ сделать это? (Я использую примитивные типы)

Я с удовольствием соглашусь с решением, которое НЕ включает скобки и запятые, такие как метод pow (a, b).

Заранее спасибо.

Теги:
caret
exponent

6 ответов

4
Лучший ответ

Следующие работы, но вы должны скомпилировать со стандартом С++ 11 (g++ -std = С++ 11 *.cpp): Вы не можете использовать оператор XOR (^) для экспонентов с примитивами. Вы должны перегрузить его внутри класса.

#include <iostream>
#include <cmath>
#include <ctgmath>

using namespace std;

class Number {
private:
    float _num;
public:
    Number(float num) : _num(num){}
    Number operator^(const float& num) {
        return Number(pow(_num,num));
    }
    float get() {
        return _num;
    }
};

int main() {
    Number a = Number(5);
    Number b = a^7;
    cout << b.get();
}
  • 1
    В реальном случае вам нужно передать класс Number оператору ^, а также перегрузить все стандартные математические операторы. Если вы хотите иметь дело с большими числами (как, например, с реализацией MATLAB), я могу предложить вам взглянуть на «infint», который позволяет рассчитывать с таким большим числом, как вы хотите: code.google. com / p / infint Я нашел это очень полезным для некоторых вещей.
  • 2
    Мне жаль следующего программиста, который должен поддерживать код, написанный с этим чудовищем.
Показать ещё 6 комментариев
4

Хотя можно перегрузить ^ чтобы сделать возведение в степень, вы не должны. Это плохая идея.

Ответ @AaronF показывает, насколько уродливым является код для этого, но это только верхушка айсберга. Реальная проблема возникает, когда вы пытаетесь на самом деле использовать это в реальном коде. Проблемы связаны с одним простым фактом: перегрузка оператора изменяет действия, выполняемые этим оператором, но не влияет ни на приоритет, ни на ассоциативность этого оператора. В случае ^ как приоритет, так и ассоциативность совершенно неверны для возведения в степень.

старшинство

В C++ оператор ^ имеет довольно низкий приоритет. Экспоненциация должна иметь очень высокий приоритет. Например, если у меня есть выражение, подобное x^y*z, я бы хотел, чтобы оно означало (x^y)*z --but то, что оно на самом деле означает x^(y*z). На самом деле, ^ имеет приоритет даже ниже сложения и вычитания, поэтому x^y+z выходит неправильно - вместо x^(y+z) вместо (x^y)+z хотеть.

Ассоциативность

Экспоненциация является правым ассоциативным --but в C++, оператор ^ остается ассоциативным. Например, учитывая выражение, подобное x^y^z, вам нужно было бы означать x^(y^z), но то, что вы получите, это (x^y)^z.

результат

Это означает, что если вы перегрузите operator^ чтобы сделать возведение в степень, вы только ушли от использования имени pow. Вы не уйдете из большинства круглых скобок; в любом нетривиальном выражении вам все равно понадобятся скобки для принудительного правильного выбора и ассоциативности, поскольку, как указано выше, приоритет и ассоциативность C++, присваиваемые operator^ являются абсолютно неправильными для возведения в степень.

Вывод

Хотя вы можете перегрузить operator^ чтобы сделать возведение в степень, это одно из тех мест, где усмотрение - лучшая часть доблести. Когда вы перегружаете операторы в C++, у вас действительно есть три фактора, которые нужно учитывать: имя, приоритет и ассоциативность. Для хорошей перегрузки оператора все три должны быть правильными. Иногда бывает разумно делать перегрузку, где только два из трех правы, а третий не слишком далеко. В этом случае только один из трех даже близко к правой; два других совершенно неверны.

Не делай этого. Это плохая идея.

  • 0
    Совершенно верно. Хорошая причина, почему многие языки даже не поддерживают перегрузку операторов.
  • 0
    @AaronF: Я не уверен, что согласен, что это хорошая причина полностью отказаться от перегрузки операторов. Это не универсально применимо, но код, использующий (для одного примера) большие целые числа в C ++ по сравнению с Java или C, дает довольно веский аргумент, что перегрузка операторов может дать значительные преимущества. Вы просто должны быть осторожны в том, как вы используете это.
2
  • Для примитивных типов (ваш случай):

    В C и C++, ^ является побитовым оператором XOR (эксклюзивный или). Вы должны использовать std::pow чтобы поднять число до мощности.

  • Для не примитивных типов вы могли бы, однако, перегрузить operator^ (но это обескураживает, так как вы будете идти против обычного значения этого оператора)

Пример:

MyClass operator^(const MyClass& t1, const MyClass& t2)
{
    //return ...
}
1

Вы не можете сделать это для примитивных типов. Вам нужно будет использовать std::pow. Вы можете сделать это для пользовательских типов, перегружая оператор ^, но это может быть не очень хорошая идея, если XOR не имеет смысла для вашего типа.

(Через 10 минут после того, как я скажу, что кто-то придумает ужасный, ужасный взлом для примитивных типов с пользовательским типом, неявные преобразования, пользовательский литерал и перегруженный оператор ^).

  • 0
    LoLz. С надеждой. Вот чего я жду.
  • 0
    +1, ТК Смотри ужасный, ужасный взлом выше. :)
0

кажется, вы ищете, чтобы кто-то сказал написать a ^ b: D, вы должны использовать предопределенные функции или написать новый;)

0

pow() в библиотеке cmath. Дополнительная информация о

http://en.cppreference.com/w/cpp/numeric/math/pow

Ещё вопросы

Сообщество Overcoder
Наверх
Меню