我正在运行一个程序,我继续在一个大循环中递增“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代码。
问题
我错过了什么?为什么我这样一个微不足道的操作会得到错误的结果?
问题的正当性
建议的副本与我的问题无关,因为它定义了宏函数,而且它没有解释为什么预处理器的行为方式。它只解释了宏功能的执行方式。
我的问题得到了很好的解释,并由产生解释行为的代码进行备份。请查看回答此问题的人如何理解问题的原因没有问题。
答案 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)