简体   繁体   English

使用stdint.h和ANSI printf?

[英]Using stdint.h and ANSI printf?

I'm writing a bignum library, and I want to use efficient data types to represent the digits. 我正在编写一个bignum库,并且我想使用有效的数据类型来表示数字。 Particularly integer for the digit, and long (if strictly double the size of the integer) for intermediate representations when adding and multiplying. 特别是数字整数,在加法和乘法时,中间表示法使用长整数(如果严格是整数大小的两倍)。

I will be using some C99 functionality, but trying to conform to ANSI C. 我将使用一些C99功能,但尝试遵循ANSIC。

Currently I have the following in my bignum library: 目前,我的bignum库中包含以下内容:

#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;

As I haven't written a procedure to write the bignum in decimal, I have to analyze the intermediate array and printf the values of each digit. 由于我尚未编写将十进制数写入十进制的程序,因此我必须分析中间数组并打印每个数字的值。 However I don't know which conversion specifier to use with printf. 但是我不知道将哪个转换说明符与printf一起使用。 Preferably I would like to write to the terminal the digit encoded in hexadecimal. 优选地,我想将以十六进制编码的数字写入终端。

The underlying issue is, that I want two data types, one that is twice as long as the other, and further use them with printf using standard conversion specifiers. 潜在的问题是,我需要两种数据类型,一种是另一种的两倍,然后使用标准转换说明符将它们与printf一起使用。 It would be ideal if int is 32bits and long is 64bits but I don't know how to guarantee this using a preprocessor, and when it comes time to use functions such as printf that solely rely on the standard types I no longer know what to use. 如果int是32位,而long是64位,那将是理想的选择,但是我不知道如何使用预处理器来保证这一点,并且当需要使用仅依赖于标准类型的诸如printf之类的函数时,我不再知道该怎么做。采用。

You could use the macros from <inttypes.h> to help out: 您可以使用<inttypes.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
#define PRI_U_HW  PRIu32    // use for formatting a `u_hw` type
#define PRI_U_W   PRIu64    // use for formatting a `u_w` type
#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
#define PRI_U_HW  PRIu16    // use for formatting a `u_hw` type
#define PRI_U_W   PRIu32    // use for formatting a `u_w` type
#endif

Then: 然后:

printf( "some u_w variable: %" PRI_U_W "\n", u_w_var);    
printf( "some u_hw variable: %" PRI_U_HW "\n", u_hw_var);

They aren't pretty, but they're how C99 does it. 它们并不漂亮,但是C99就是这样。

ANSI C provides no guarantees about the sizes of int and long , and I don't think long long is an ANSI type. ANSI C不保证intlong的大小,我也不认为long long是ANSI类型的。 If you are unwilling or unable to use C99, the only safe, portable solution is to write a configure script that will create C programs that use sizeof to find a pair of integer types that have the property you require. 如果您不愿意或无法使用C99,则唯一安全,可移植的解决方案是编写配置脚本,该脚本将创建使用sizeof查找具有所需属性的一对整数类型的C程序。 You can then in that script generate macros including printf format macros. 然后,您可以在该脚本中生成包括printf格式宏的宏。

It's also possible that the reason you're not using C99 is that you're porting to some wacky platform without a C99 compiler. 您不使用C99的原因还可能是您要移植到一些没有C99编译器的古怪平台上。 In that case you can just figure out what works, slap it in a header, and not worry about portability. 在这种情况下,您只需找出可行的方法,将其拍打在标题中,而不必担心可移植性。

C99 isn't pretty but it sure does solve some of these annoying C problems. C99并不漂亮,但它确实可以解决其中一些令人讨厌的C问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM