C中的整数乘法不正确

时间:2017-11-22 08:38:24

标签: c c-preprocessor

Simulink中的C编码S函数显示不正确的行为,我设法将问题缩小到不正确的整数乘法。

在代码开头,我有类似的东西:

#define NRBF       21
#define NRBF1  NRBF+1

然后,在剧本的一个函数中我有:

void function_name(SimStruct *S, const int_T a)
{
...
    int_T base;
    base = a*NRBF1;
    printf("%i\t", a);
    printf("%i\t", NRBF1);
    printf("%i\n", base);
..
}

现在,如果a=0NRBF=21,我有(而不是base=0

0  22  1

如果a=1NRBF=21,我有(按预期base=22

1  22  22

如果a=2NRBF=21,我有(而不是base=44

2  22  43 

现在,我必须说我有点困惑。我试图将乘法线改为

base = a* (int_T)NRBF1;

但它没有解决问题。

任何帮助将不胜感激!谢谢!

4 个答案:

答案 0 :(得分:5)

问题在于:

您可以像这样定义宏:

#define NRBF       21
#define NRBF1  NRBF+1

当你这样写:

base = a*NRBF1;

预处理器用NRBF1以文本方式替换21+1,结果如下:

base = a*21+1;

但你打算这样做:

base = a*(21+1);

因此,您需要像这样定义宏:

#define NRBF1  (NRBF+1)

答案 1 :(得分:3)

随着宏的扩展,该行看起来像:

base = a*NRBF+1;
  • 如果a等于0,则表达式为0 * 21 + 1,即1。
  • 如果a等于2,则表达式为2 * 21 + 1,即43。

解决方案是将括号放在宏定义中:

#define NRBF1 (NRBF + 1)

对于任何以表达式为右侧的宏来说,这是一个很好的规则。

请记住,宏只是文本替换为代码。

答案 2 :(得分:2)

基本上计算好了

0*21+1 = 1

宏已展开,但*优先于+。这就是为什么会发生这种情况。

更详细的解释是

#define NRBF       21
#define NRBF1  NRBF+1

那是怎么回事?

base = a*NRBF1;

base = a*NRBF+1

Now when a = 0 then base = 1
    when a = 1 then base = 21+1 ...so on.

正确的方法是用aropund括号括起来。

#define NRBF1  (NRBF+1)

更多陷阱:

当您添加像#define SQR(X) X*X

这样的宏时

对于像这样的一些例子,其中相同的优先级运算符紧挨着下一个,那么它将是有问题的。

int i = 100/SQR(10);

然后它将扩展为

int i = 100/10*10

现在,从左到右执行相同的优先级运算符。

因此会产生i=100

同样的解决方案#define SQR(X) (X*X)

同样,当传递像SQR(i+1)这样的表达式时,它会扩展为i+1*i+1 = 2*i+1。所以更正确的是

#define SQR(X) ((X)*(X))

即使如此,如果你忘记了一件事,你就无法避免一些事情宏只是扩展 - 它什么都不做

你不能像这样使用宏

SQR(i++)将扩展为((i++)*(i++))。所以你增加了i两次,这是你不是故意的。此外,这将导致未定义的行为

答案 3 :(得分:1)

define不会创建单个值22但是表达式为21 + 1.我想知道如果将第二个#define更改为  #define NBRF1(NBRF + 1)