Sympy中的整数算术

时间:2017-09-01 09:22:37

标签: python sympy

我试图将整数x除以常数:

>>> x = sympy.Symbol("x", integer=True)
>>> (x + 4 - 1) // 4
floor(x/4 + 3/4)

如果我们从sympy 的上下文中取出,则在假设整数运算时表达式是不正确的。 例如,在python 2.7中:

>>> floor(9/4 + 3/4)
2.0

我想要的是一个表达式,当在不同的上下文中进行评估时,会生成所需的(9 + 3) / 4 = 3

到目前为止的解决方案:

sympy.Mul(x + 4 - 1, sympy.Pow(4, -1), evaluate=False)
sympy.factor((x + 4 - 1) / 4)

虽然这些都给出了所需的(x + 3)/4,但必须为每个表达式明确地完成它们。

我正在寻找以下内容:

>>> sympy.assume_integer()
>>> (x + 4 - 1) // 4
(x + 3) / 4

上下文:我们的项目使用SymPy生成C ++,因此我们从sympy表达式生成 string ,需要在整数运算下正确计算。 虽然floor(x/4 + 3/4).subs(x, 9)确实产生3,但这不是我们将评估表达式的上下文。

答案documentation表明了以下内容:

>>> ((x+4-1-(x+4-1)%4)/4)      
x/4 - Mod(x + 3, 4)/4 + 3/4

与上述问题相同,即3/4不是整数。

2 个答案:

答案 0 :(得分:2)

如果您想要生成C ++代码,则应使用专为此目的而设计的SymPy’s code printers。例如:

from sympy.abc import x
from sympy.printing import cxxcode

expr = (x+3)//4
print(cxxcode(expr))
# 'floor((1.0L/4.0L)*x + 3.0L/4.0L)'

将其插入C ++代码:

# include <stdio.h>
# include <math.h>

int main()
{
    int x = 9;
    printf("%Lf\n", floor((1.0L/4.0L)*x + 3.0L/4.0L));
}

这会产生3.000000。如果需要,您需要convert the result to an integer

答案 1 :(得分:0)

我想你可以使用sympy的因子方法。

import sympy as sym
x = sym.symbols('x', integer=True)
sym.factor((x + 4 - 1) /4)

这会产生(x+3)/4。这就是你想要的吗?

或尝试

sym.floor(sym.factor((x + 4 - 1) /4))

如果你想要floor((x+3)/4)

修改

您可以定义自己的打印功能:

def arith_print(x):
    print(sym.floor(sym.factor(x)))

这将采用您目前为止所显示的任何表达式,并以算术精度兼容的方式进行打印。

P.S。:要让>>> (x + 4 - 1) // 4工作,需要一个充分最新版本的同情。 0.7.6太旧了。