Question

Je veux multiplier le nombre de longs qui sont donnés dans une base 2 ^ 32. Je l'ai déjà pensé à un bel algorithme pour le faire, mais malheureusement, je suis coincé. La situation dans laquelle je suis coincé à, comment je le fais multiplier deux longues ints et représente sur la base 2 ^ 32.

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef unsigned int uint32;
typedef unsigned long long uint64;
int main(int argc, char* argv[] )
{

  uint64 a = (uint64)ULONG_MAX;
  printf("%llu\n", a);
  uint64 b = (uint64)ULONG_MAX;  
  printf("%llu\n", b);  
  uint64 c = (uint64)(a*b);

  printf("%llu\n", c);  // prints 1. that would be to lower 32 bits of the results. the upper half is 0xFFFFFFFE

  printf("%llu\n", ULLONG_MAX);
  system("pause");
}

Pourquoi est-ULLONG_MAX même que ULONG_MAX? Selon http://en.wikipedia.org/wiki/Limits.h#Member_constants il devrait être 18.446.744.073.709.551.615 I

Comme vous pouvez le voir de mes commentaires, je veux le résultat de l'Multiplikation dans les deux uint32. Le lowerhalf serait 0x1 et la moitié supérieure 0xFFFFFFFE. Comment puis-je obtenir ces valeurs?

(je trouve cette question sur le SO, mais ce n'est pas utile dans ma situation parce que les réponses ar mes idées similaire: multiplication de deux long long ints C )

Edit: Mon système est Windows XP 32 bits. J'utilise gcc 3.4.2 (MinGW-spéciale)

La sortie je ne reçois pendant l'exécution du code:

4294967295
4294967295
1
4294967295

Edit2:

  printf("%i\n", sizeof(unsigned long));
  printf("%i\n", sizeof(unsigned long long)); 

retourne

4
8

Edit 3: Merci à Petesh j'ai pu trouver la solution:

  printf("%lu\n", c & 0xFFFFFFFF);
  printf("%lu\n", (c >> 32));
Était-ce utile?

La solution

L'indice est dans le système ( « pause ») - vous êtes sur Windows? Impression d'un long long en utilisant le moteur d'exécution Microsoft Visual C nécessite l'utilisation '% I64u' (qui est un i majuscule).

Ceci est basé sur SO question Comment printf-vous un unsigned long int (le spécificateur de format pour longtemps à long unsigned int)?

Autres conseils

Je ne sais pas pourquoi vous obtenez ces résultats avec votre (non spécifié) compilateur mais gcc sous Ubuntu 10 donne:

4294967295
4294967295
18446744065119617025
18446744073709551615

avec ces deux derniers étant 0xfffffffe00000001 et (2 64 -1), respectivement, comme désiré.

considérer Alors peut-être passer à un compilateur plus mis à jour. Peut-être que vous utilisez un compilateur pré-C99.

Juste d'intérêt, ce qui ne sizeof (unsigned long) et sizeof (unsigned long long) vous donner sur votre système. Cela irait un long chemin à expliquer votre problème.


Un couple d'autres choses à vérifier depuis votre sizeofs semblent indiquer les types de données eux-mêmes sont d'accord (bien que ceux-ci ne peuvent pas résoudre le problème - ils ont été trouvés avec recherche sur le web assez peu profonde ):

  • Essayez d'utiliser "%I64u" comme la chaîne de format au lieu de "%llu". Si MinGW utilise les libs msvcrt, qui pourraient être nécessaires pour un véritable soutien de printf 64 bits.
  • Assurez-vous de la compilation avec -std=c99.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top