c ++ 11:pow的简短表示法?

时间:2014-10-16 22:51:10

标签: c++ c++11

我需要将大量公式粘贴到我的c ++ 11代码中。 这个公式包含很多东西,比如double类型到整数幂: formula

写作很无聊:

pow(sin(B), 6) + ... pow(sin(C), 4) + ....

20次

最好的事情是重载operator ^ for double和int, 但据我所知,C ++ 11是不可能的。在这样的公式中:

z0^2 * (something)

根据运算符的优先级,它将是这样的:

z0 ^ (2 * (something)) 

这不是我想要的。

那么使用C ++代码可以使用一些技巧来近似x的幂数来计算y的幂?

可能的toools是:c ++ 11和boost。

更新

关于使用这种数学符号而不是C ++的支持代码。

我认为理想的解决方案就像:

const double result = (latex_mode
    (sin(B_0))^6(a + b)
    latex_mode_end)
    (B_0, a, b);

其中latex_mode支持LaTex语言的小部分而没有歧义。 1)所有触摸此代码的程序员都有数学背景,因此他们会毫无问题地阅读乳胶 2)配方可以从文章复制/粘贴,无需任何修改, 所以它会减少拼写错误。

2 个答案:

答案 0 :(得分:5)

不,你不能这样做。至少,你不应该。但它可以简化。如果您的公式可以描述为http://mathurl.com/nflxcb8.png,那么您可以创建成对表(a,b)并编写本身将执行此操作的代码。例如:

  vector<pair<unsigned, unsigned>> table = {{1, 2}, {2, 3}, {3, 4}};
  unsigned sum = 0; 
  for(const auto& x : table)
    sum += pow(get<0>(x), get<1>(x));

受到@ 5gon12eder评论的启发,我写了一个函数:

template <typename Input, typename Output = unsigned>
Output powers(std::initializer_list<Input> args) {
  Output result = 0;
  for(const auto x : args)
   result += pow(std::get<0>(x), std::get<1>(x));
  return result;
 }

您需要其他(标准)库:

  1. #tuple
  2. #initializer_list
  3. 使用示例:

    std::pair<unsigned, unsigned> a{1,2}, b{2,3};
    std::cout << powers({a, b, {3, 4}, {4,5}}) << '\n';
    

    打印1114it's correct


    参考编辑部分,我建议写一个接收字符串和解析的函数。但它比上述方法慢得多。 最后,您可以写信给编译器的作者。

    修改: 随着C ++ 14出现了新的可能性。你可以用for,变量等来创建constexpr函数。因此创建编译时解析器更容易。我仍然建议从帖子的原始部分解决,因为它会有点乱,但它会在编译时做你想要的。

    String to int example:

    #include <iostream>
    
    
    template<size_t N>
    constexpr uint32_t to_int(const char (&input)[N]) { // Pass by reference
        uint32_t result = 0;
        for(uint32_t i = 0; i < N && input[i] != '\0'; ++i) {
            result *= 10;
            result += input[i] - '0';
        }
    
        return result;
    }
    
    constexpr uint32_t value = to_int("123427");
    
    enum { __force_compile_time_computing = value };
    
    int main() {
        std::cout << value << std::endl;
    }
    

    打印:

    ~ $ g++ -std=c++14 -Wall -Wextra -pedantic-errors example.cpp 
    ~ $ ./a.out 
    123427
    ~ $
    

    显然,制作解析器会更难。可能最好的方法是使用两个构造函数Operation(operation, operation)Operation(value)创建constexpr类操作,并在编译时创建计算树(如果字符串中有变量)。


    如果您不想完成这项工作,并且您可以接受其他程序/语言语义,那么您可以实现简单的运行时解决方案。创建调用R / mathematica / {something else}并向其发送输入字符串的新线程。计算后重新发送值到主程序。 如果你想要一些提示,可能使用std::future会很方便。

答案 1 :(得分:3)

仅供记录,这就是Bjarne Stroustrup says about it

  

我可以定义自己的运营商吗?

     

抱歉,没有。这种可能性已被多次考虑过,但每次我/我们认为可能的问题超过了可能的好处。

     

这不是语言技术问题。即使我在1983年首次考虑它,我也知道它是如何实现的。然而,我的经验是,当我们超越最微不足道的例子时,人们似乎对运营商使用的“明显”含义有着微妙的不同看法。一个经典的例子是a**b**c。假设已**表示取幂。我应该a**b**c表示(a**b)**c还是a**(b**c)?我认为答案很明显,我的朋友们同意了 - 然后我们发现我们并不同意哪个决议是明显的。我的猜想是,这些问题会导致细微的错误。

有趣的是,它正是您所缺少的运营商。嗯,这并不是一个巧合,因为许多人都缺少一个内置的取幂运算符。特别是那些了解Fortran或Python的人(两种语言,否则很少一起提及)。