C ++ - 多个#DEFINE值会导致简单的算术失败

时间:2017-12-05 16:31:41

标签: c++ long-integer division

我正在运行一个程序,我继续在一个大循环中递增“long int”(该值预计最多为10 ^ 8)。有问题的“long int”初始化为0.我的控制台打印如下所示:

  

错误消息:400000/5000 = 800000个实例

请注意分歧不正确。代码打印上面的行:

std::cout << "errorous messages   : " << total_error << "/" << GRID_SIZE << " = " << (long)((long)total_error / (long)GRID_SIZE) << " instances" << std::endl;

有问题的变量是:

#define BLOCKS      50
#define THREADS     100
#define GRID_SIZE   BLOCKS*THREADS

long int total_error;  <--- incremented in a loop (never decremented, no overflow)

我尝试了什么

我一直在重复(long)((long)total_error / (long)GRID_SIZE)(long)(total_error / GRID_SIZE)和其他一些人的划分,结果是一样的。

编辑信息

 /opt/ohpc/pub/mpi/openmpi-gnu/1.10.6/bin/mpicxx 
-I../../common/inc -I/usr/local/cuda-8.0/include 
-I/export/home/ra2/test_cuda/test_cuda_v0_1/source_code 
-I/export/home/ra2/test_cuda/test_cuda_v0_1/source_code/Utility 
-I/export/home/ra2/test_cuda/test_cuda_v0_1/source_code/Data_objects 
-I/export/home/ra2/test_cuda/test_cuda_v0_1/source_code/cereal   
-std=c++11    -o main.o -c main.cpp

我正在使用OpenMPI进行编译。还有CUDA,但这是main.cpp,没有CUDA代码。

问题

我错过了什么?为什么我这样一个微不足道的操作会得到错误的结果?

问题的正当性

  • 建议的副本与我的问题无关,因为它定义了宏函数,而且它没有解释为什么预处理器的行为方式。它只解释了宏功能的执行方式。

  • 我的问题得到了很好的解释,并由产生解释行为的代码进行备份。请查看回答此问题的人如何理解问题的原因没有问题。

2 个答案:

答案 0 :(得分:3)

#define GRID_SIZE   BLOCKS*THREADS

应该是

#define GRID_SIZE   (BLOCKS*THREADS)

或更好

const int GRID_SIZE = BLOCKS*THREADS; 

答案 1 :(得分:2)

因为#define只是文字替换,所以

(long)((long)total_error / (long)GRID_SIZE)

扩展为

(long)((long)total_error / (long)BLOCKS*THREADS)

并且,因为除法(/)和乘法(*)运算符具有相同的优先级,所以整个表达式从左到右进行求值,实际上等于:

  

400000/50 * 100 = 8000 * 100 = 800000

考虑在#define s括号内完成包装计算,以防止出现此类问题:

#define GRID_SIZE   (BLOCKS*THREADS)