C++ - 多个#DEFINE 值导致简单算术失败
C++ - multiple #DEFINE values cause simple arithmetics to fail
我是一个 运行 程序,我在一个大循环中不断递增 "long int"(预期值最大为 10^8)。有问题的 "long int" 初始化为 0。我的控制台打印如下所示:
errorous messages : 400000/5000 = 800000 instances
请注意除法不正确。代码打印上面的行:
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 代码。
问题
我错过了什么?为什么这么简单的操作我会得到错误的结果?
问题的理由
提议的副本与我的问题无关,因为它定义了宏函数,而且它没有解释为什么预处理器的行为如此。它只是解释宏函数的执行方式。
我的问题得到了很好的解释,并得到了产生解释行为的代码的支持。请看看回答这个问题的人是如何理解问题的原因的。
#define GRID_SIZE BLOCKS*THREADS
应该是
#define GRID_SIZE (BLOCKS*THREADS)
或更好
const int GRID_SIZE = BLOCKS*THREADS;
因为 #define
s 只是文本替换,所以你的
(long)((long)total_error / (long)GRID_SIZE)
扩展为
(long)((long)total_error / (long)BLOCKS*THREADS)
并且,因为除法 (/
) 和乘法 (*
) 运算符具有相同的优先级,所以整个表达式从左到右求值,实际上等于:
400000 / 50 * 100 = 8000 * 100 = 800000
考虑在括号中 #define
秒内完成的换行计算,以防止出现此类问题:
#define GRID_SIZE (BLOCKS*THREADS)
我是一个 运行 程序,我在一个大循环中不断递增 "long int"(预期值最大为 10^8)。有问题的 "long int" 初始化为 0。我的控制台打印如下所示:
errorous messages : 400000/5000 = 800000 instances
请注意除法不正确。代码打印上面的行:
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 代码。
问题
我错过了什么?为什么这么简单的操作我会得到错误的结果?
问题的理由
提议的副本与我的问题无关,因为它定义了宏函数,而且它没有解释为什么预处理器的行为如此。它只是解释宏函数的执行方式。
我的问题得到了很好的解释,并得到了产生解释行为的代码的支持。请看看回答这个问题的人是如何理解问题的原因的。
#define GRID_SIZE BLOCKS*THREADS
应该是
#define GRID_SIZE (BLOCKS*THREADS)
或更好
const int GRID_SIZE = BLOCKS*THREADS;
因为 #define
s 只是文本替换,所以你的
(long)((long)total_error / (long)GRID_SIZE)
扩展为
(long)((long)total_error / (long)BLOCKS*THREADS)
并且,因为除法 (/
) 和乘法 (*
) 运算符具有相同的优先级,所以整个表达式从左到右求值,实际上等于:
400000 / 50 * 100 = 8000 * 100 = 800000
考虑在括号中 #define
秒内完成的换行计算,以防止出现此类问题:
#define GRID_SIZE (BLOCKS*THREADS)