J'écris une bibliothèque bignum, et je veux utiliser des types de données efficaces pour représenter les chiffres. Particulièrement entier pour le chiffre, et long (si strictement double de la taille de l'entier) pour les représentations intermédiaires lors de l'addition et de la multiplication.Avec stdint.h et ANSI printf?
Je vais utiliser certaines fonctionnalités de C99, mais en essayant de se conformer à la norme ANSI C.
Actuellement, je suis ce qui suit dans ma bibliothèque 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;
Comme je l'ai pas écrit une procédure écrire le bignum en décimal, je dois analyser le tableau intermédiaire et imprimer les valeurs de chaque chiffre. Cependant, je ne sais pas quel spécificateur de conversion utiliser avec printf. De préférence je voudrais écrire au terminal le chiffre codé en hexadécimal. Le problème sous-jacent est que je veux deux types de données, un qui est deux fois plus long que l'autre, et les utilise en outre avec printf en utilisant des spécificateurs de conversion standard. Il serait idéal si int est 32bits et long est 64bits mais je ne sais pas comment le garantir en utilisant un préprocesseur, et quand vient le temps d'utiliser des fonctions telles que printf qui reposent uniquement sur les types standard je ne sais plus quoi utilisation.
Vous voulez inclure les définitions entre guillemets? Quoi qu'il en soit, un conseil pratique. Je pensais que cela serait documenté dans la page de manuel printf, mais je me demandais comment C99 traiterait de ces types. Merci. – snap
Dans la première partie de l'exemple où ils sont définis, 'PRI_U_HW' et' PRI_U_W' sont simplement des alias pour les valeurs C99 'PRIuXX', qui seront des littéraux de chaîne. Quand vous allez les utiliser (comme dans les exemples 2 'printf() dans le 2ème extrait de code) vous devez les utiliser en dehors des guillemets (ils fournissent leurs propres guillemets) et s'appuyer sur la concaténation de littéraux adjacents de C dans ' phase 6 'de la traduction. Comme je l'ai dit, c'est plutôt moche. –
Je vois. Au fait, pensez-vous qu'il y a de toute façon à éviter ce gunk de processeur et s'en tenir à int/long? J'ai vraiment juste besoin d'avoir deux types, dont l'un est au moins le double de la largeur. Je suppose que char et short feraient l'affaire, mais je préfèrerais utiliser les types de données plus grands tels que int/long/long long si possible. – snap