我正在编写一个大数库,并希望使用高效的数据类型来表示数字。特别是对于数字,我将使用整数类型,对于加法和乘法的中间结果,我将使用长整型(如果严格双倍于整数类型)。
我会使用一些C99功能,但尽可能符合ANSI C标准。
目前我的大数库中包含以下内容:
由于我还没有编写将大数以十进制形式写入的过程,因此我必须分析中间数组并使用printf打印每个数字的值。然而,我不知道在printf中使用哪种转换说明符。最好是将16进制编码的数字写入终端。
根本问题在于,我想要两种数据类型,一种比另一种长两倍,并使用标准的转换说明符与printf一起使用。如果int为32位且long为64位,则最理想。但是我不知道如何使用预处理器来保证这一点,当使用仅依赖于标准类型的函数(如printf)时,我不再知道该使用什么。
我会使用一些C99功能,但尽可能符合ANSI C标准。
目前我的大数库中包含以下内容:
#include <stdint.h>
#if defined(__LP64__) || defined(__amd64) || defined(__x86_64) || defined(__amd64__) || defined(__amd64__) || defined(_LP64)
typedef uint64_t u_w;
typedef uint32_t u_hw;
#define BIGNUM_DIGITS 2048
#define U_HW_BITS 16
#define U_W_BITS 32
#define U_HW_MAX UINT32_MAX
#define U_HW_MIN UINT32_MIN
#define U_W_MAX UINT64_MAX
#define U_W_MIN UINT64_MIN
#else
typedef uint32_t u_w;
typedef uint16_t u_hw;
#define BIGNUM_DIGITS 4096
#define U_HW_BITS 16
#define U_W_BITS 32
#define U_HW_MAX UINT16_MAX
#define U_HW_MIN UINT16_MIN
#define U_W_MAX UINT32_MAX
#define U_W_MIN UINT32_MIN
#endif
typedef struct bn
{
int sign;
int n_digits; // #digits should exclude carry (digits = limbs)
int carry;
u_hw tab[BIGNUM_DIGITS];
} bn;
由于我还没有编写将大数以十进制形式写入的过程,因此我必须分析中间数组并使用printf打印每个数字的值。然而,我不知道在printf中使用哪种转换说明符。最好是将16进制编码的数字写入终端。
根本问题在于,我想要两种数据类型,一种比另一种长两倍,并使用标准的转换说明符与printf一起使用。如果int为32位且long为64位,则最理想。但是我不知道如何使用预处理器来保证这一点,当使用仅依赖于标准类型的函数(如printf)时,我不再知道该使用什么。
PRI_U_HW
和PRI_U_W
只是C99PRIuXX
值的别名,它们将成为字符串字面量。当您使用它们(如第二个代码片段中的2个printf()
示例)时,必须在引号外使用它们(它们提供自己的引号),并依赖于C执行的相邻字符串字面量的连接,在翻译的“第6阶段”执行。就像我说的,这有点丑陋。 - Michael Burr