对于手头的情况,您可以使用以下内容:
Clear[getCFormNoPowers];
getCFormNoPowers[expr_] :=
Module[{times},
Apply[Function[code, Hold[CForm[code]], HoldAll],
Hold[#] &[expr /. x_Symbol^y_Integer /; y > 1 :>
times @@ Table[x, {y}]] /. times -> Times]];
例如,
In[52]:= getCFormNoPowers[2 hgt^2 k1inv^3 mx0 wid^2+hgt^2 k1inv^3 wid^3]
Out[52]= Hold[2*mx0*(hgt*hgt)*(wid*wid)*(k1inv*k1inv*k1inv) +
hgt*hgt*(k1inv*k1inv*k1inv)* (wid*wid*wid)]
结果被包裹在Hold 中,以防止其评估返回到Power-s。您可以将其转换为
任何时候的字符串,使用类似ToString[HoldForm@@result]的东西。或者您可以进一步操作。
编辑:
您也可以这样做:
Clear[getCFormNoPowers];
getCFormNoPowers[expr_] :=
Block[{Times},
SetAttributes[Times, {Flat, OneIdentity}];
Apply[Function[code, Hold[CForm[code]], HoldAll],
Hold[#] &[expr /. x_Symbol^y_Integer /; y > 1 :> Times @@ Table[x, {y}]]]];
这也将保持您的条款的原始顺序,并去掉不必要的括号,所以这个似乎完全符合您的规范。
一般来说,您可能想看看版本 8 的新“符号 C 生成”功能。将您的代码映射到符号 C 表达式可能是一种更健壮的方法。这样一来,您就不必一直担心求值,最后您可以使用新功能生成整个 C 程序。
编辑 2:
为了说明如何使用 SymbolicC 解决问题:
Needs["SymbolicC`"];
Clear[getCFormNoPowersSymC];
getCFormNoPowersSymC[expr_] :=
Block[{Times},
SetAttributes[Times, {Flat, Orderless}];
ToCCodeString[
expr /. x_Symbol^y_Integer /; y > 1 :> Times @@ Table[x, {y}] //.
HoldPattern[(op : (Times | Plus))[args__]] :> COperator[op, {args}]]];
In[53]:= getCFormNoPowersSymC[2 hgt^2 k1inv^3 mx0 wid^2+hgt^2 k1inv^3 wid^3]
Out[53]= 2 * hgt * hgt * k1inv * k1inv * k1inv * mx0 * wid * wid +
hgt * hgt * k1inv * k1inv * k1inv * wid * wid * wid
这种方法 IMO 有几个优点。也许两个主要的是可组合性(一个可以将这样的表达式嵌套在它们的符号形式中,从较小的代码块构建更大的代码块),以及一个不需要太多考虑评估的事实(我不需要任何技巧) Hold 这里)。