2010-07-26 5 views
1

I ont le code suivant:Calculer le pourcentage de 64 int

typedef __int64 BIG_INT; 
typedef double CUT_TYPE; 

#define CUT_IT(amount, percent) (amount * percent) 

void main() 
{ 
    CUT_TYPE cut_percent = 1; 

    BIG_INT bintOriginal = 0x1FFFFFFFFFFFFFF; 
    BIG_INT bintAfter = CUT_IT(bintOriginal, cut_percent); 
} 

la valeur de bintAfter après le calcul est 144115188075855872 au lieu d'144115188075855871 (voir le "2" à la fin, au lieu de "1" ??).

Sur des valeurs plus petites telles que 0xFFFFFFFFFFFFF, j'obtiens le résultat correct.
Comment puis-je le faire fonctionner, sur l'application 32 bits? Qu'est-ce que je dois prendre en compte?
Mon but est de couper un certain pourcentage d'un très grand nombre.

J'utilise VC++ 2008, Vista.

+0

Est-ce que "cut_percent" va toujours être n/100 pour un entier n, ou est ce que "cut_percent" peut être un double arbitraire? –

+0

@Peter: double arbitraire c'est. L'exemple de code utilise 100% juste pour souligner le fait que la valeur est fausse, peu importe comment vous le regardez. – Poni

Répondre

5

double a une mantisse 52 bits, que vous perdez la précision lorsque vous essayez de charger une valeur de bit 60+ en elle.

+0

J'utilise habituellement 'long double' sur g ++, ce qui donne une plus grande précision. Après avoir vérifié, il semble que VC++ ne respecte pas vraiment cela. http://en.wikipedia.org/wiki/Long_double –

3

Il n'est pas certain que les calculs de virgule flottante soient parfaitement précis et vous avez défini CUT_TYPE comme double.

Voir cette réponse pour plus d'info: Dealing with accuracy problems in floating-point numbers

+0

Je sais que je devrais "accepter" une certaine gamme, même si j'espère que quelqu'un trouvera un moyen de contourner ce problème. – Poni

+2

La solution consiste à utiliser une bibliothèque bignumber prenant en charge une précision arbitraire et des nombres rationnels. –

Questions connexes