c++ - 我可以使用 C/C++ 预处理器添加数字吗?

标签 c++ c metaprogramming preprocessor

对于一些基地。基数 1 偶数。某种复杂的替换。

当然,在现实生活中的生产代码中这样做并不是一个好主意。我只是出于好奇而问。

最佳答案

您可以相对容易地编写在二进制中添加两个整数的宏。例如 - 将两个 4 位整数二进制相加的宏:

#include "stdio.h"

// XOR truth table
#define XOR_0_0 0
#define XOR_0_1 1
#define XOR_1_0 1
#define XOR_1_1 0

// OR truth table
#define OR_0_0 0
#define OR_0_1 1
#define OR_1_0 1
#define OR_1_1 1

// AND truth table
#define AND_0_0 0
#define AND_0_1 0
#define AND_1_0 0
#define AND_1_1 1

// concatenation macros
#define XOR_X(x,y) XOR_##x##_##y
#define   OR_X(x,y) OR_##x##_##y
#define  AND_X(x,y) AND_##x##_##y
#define OVERFLOW_X(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) OVERFLOW_##rc1 (rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4)

// stringification macros
#define STR_X(x) #x
#define STR(x) STR_X(x)

// boolean operators
#define XOR(x,y) XOR_X(x,y)
#define   OR(x,y) OR_X(x,y)
#define  AND(x,y) AND_X(x,y)

// carry_bit + bit1 + bit2
#define BIT_SUM(carry,bit1,bit2) XOR(carry, XOR(bit1,bit2))
// carry_bit + carry_bit_of(bit1 + bit2)
#define CARRY_SUM(carry,bit1,bit2) OR(carry, AND(bit1,bit2))

// do we have overflow or maybe result perfectly fits into 4 bits ?
#define OVERFLOW_0(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) SHOW_RESULT(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4)
#define OVERFLOW_1(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) SHOW_OVERFLOW(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4)

// draft-horse macros which performs addition of two 4-bit integers
#define ADD_BIN_NUM(a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_4(0,0,0,0, 0,0,0,0, a1,a2,a3,a4, b1,b2,b3,b4)
#define ADD_BIN_NUM_4(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_3(rc1,rc2,rc3,AND(CARRY_SUM(0,a4,b4),OR(a4,b4)), rb1,rb2,rb3,BIT_SUM(0,a4,b4), a1,a2,a3,a4, b1,b2,b3,b4)
#define ADD_BIN_NUM_3(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_2(rc1,rc2,AND(CARRY_SUM(rc4,a3,b3),OR(a3,b3)),rc4, rb1,rb2,BIT_SUM(rc4,a3,b3),rb4, a1,a2,a3,a4, b1,b2,b3,b4)
#define ADD_BIN_NUM_2(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) ADD_BIN_NUM_1(rc1,AND(CARRY_SUM(rc3,a2,b2),OR(a2,b2)),rc3,rc4, rb1,BIT_SUM(rc3,a2,b2),rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4)
#define ADD_BIN_NUM_1(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4)      OVERFLOW(AND(CARRY_SUM(rc2,a1,b1),OR(a1,b1)),rc2,rc3,rc4, BIT_SUM(rc2,a1,b1),rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4)
#define OVERFLOW(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) OVERFLOW_X(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4)
#define   SHOW_RESULT(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) STR(a1) STR(a2) STR(a3) STR(a4) " + " STR(b1) STR(b2) STR(b3) STR(b4) " = " STR(rb1) STR(rb2) STR(rb3) STR(rb4)
#define   SHOW_OVERFLOW(rc1,rc2,rc3,rc4, rb1,rb2,rb3,rb4, a1,a2,a3,a4, b1,b2,b3,b4) STR(a1) STR(a2) STR(a3) STR(a4) " + " STR(b1) STR(b2) STR(b3) STR(b4) " = overflow"

void main()
{
    printf("%s\n", 
        ADD_BIN_NUM(
                    0,0,0,1, // first  4-bit int
                    1,0,1,1) // second 4-bit int
                    );

    printf("%s\n", 
        ADD_BIN_NUM(
                    0,1,0,0, // first  4-bit int
                    0,1,0,1) // second 4-bit int
                );

    printf("%s\n", 
        ADD_BIN_NUM(
                    1,0,1,1, // first  4-bit int
                    0,1,1,0) // second 4-bit int
                );
}

这个宏可以很容易地扩展为添加两个 8 位或 16 位甚至 32 位整数。 因此,基本上我们所需要的只是 token 连接和替换规则,以使用宏实现惊人的结果。

编辑: 我更改了结果的格式,更重要的是 - 我添加了溢出检查。

HTH!

关于c++ - 我可以使用 C/C++ 预处理器添加数字吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3539549/

相关文章:

c++ - 使用多重继承时,类可以知道父类(super class)吗?

c++ - [defns.prog.def.spec] 中的 `⟨library⟩` 是什么意思?

C 编程 bool 表达式

c - 读/写自堆

c++ - Boost.Fusion 运行时开关

c++ - 解决功能模板部分特化

c++ - printf 网络数据

c - 如何在 C 中对 double 进行精确舍入而不用零

c - C语言中有什么奇怪的用法

Ruby - 与对象的特征类共享局部变量