2017-10-18 40 views
2

Dans mon programme, je dois effectuer des opérations arithmétiques sur des entiers non signés.Multiplication et division entiers non signés

  • L'une variable présente une plage de 0 à 4294967295.
  • La variable b est compris entre 0 et 32.

Quand je vérifie la condition aux limites en prenant les valeurs maximun pour un et b, je reçois 0 comme réponse puisque le débordement se produit quand j'essaye de multiplier un et MAX_NS. Idéalement je devrais obtenir 7 comme réponse. Comment pourrais-je écrire le programme tel que le débordement est pris en charge et je obtenir 7 comme la réponse et j'espère que cela fonctionne pour d'autres gamme de valeur valide pour a et b.Merci.

#include "stdio.h" 

#define MAX_NS 1000000000 

int main() 
{ 
    unsigned int a = 4294967295; 
    unsigned int b = 32 ; 

    unsigned int c = ((b * MAX_NS)/a); 
    printf("%d",c); 


} 

** Edit: ** S'il vous plaît noter que je ne peux pas utiliser long.I unsigned long ne peut utiliser que unsigned int pour les variables.

+1

En utilisant 'unsigned long long'? Vous divisez par la valeur max non signée, de sorte que tous les résultats (sauf un) compris dans la plage de 'unsigned int' seront' 0'. –

+0

Il n'y a aucun moyen d'utiliser l'ordre des opérations seul pour obtenir le même résultat que si les calculs étaient effectués avec des intermédiaires de taille arbitraire. Il y a peut-être des astuces spécifiques aux valeurs d'entrée (plus simple: 'c = 7;'), mais à part celles-ci, le mieux que vous pouvez faire est de promouvoir explicitement un type plus large, comme 'uintmax_t'. –

+0

Je ne vois pas pourquoi vous attendez que la réponse soit 7. La réponse de précision complète aura les cinq bits de poids faible tout à zéro, et les 32 bits au-dessus de tout cela. Comment obtenez-vous 7 de cela? –

Répondre

1

Voici la solution que Girouette a suggéré

#include "stdio.h" 

#define MAX_NS 1000000000 

int main() 
{ 
    unsigned long long a = 4294967295; 
    unsigned long long b = 32; 

    unsigned long long c = ((b * MAX_NS)/a); 
    printf("%llu", c); 
} 
+0

imprime de toute façon, mais vous avez raison, devrait être llu – vlada

+0

mais même quand j'utilise une plus petite valeur 'a' (supposons 50000000), je ne reçois pas le bonne réponse.Serait 640 mais je reçois 38.Quelle pourrait être la raison? –

+0

Quelque chose d'autre doit être un problème. J'ai vérifié ce code et il imprime 7. – vlada

0

La clé est que le produit doit être b * MAX_NS calculée en utilisant les mathématiques assez large.

Assurez-vous qu'au moins l'un des opérandes * est unsigned long long.

Avec suffisamment grand b et assez petit a, le quotient aura besoin d'un type plus large pour éviter le débordement;

#include "stdio.h" 
// #define MAX_NS 1000000000 
#define MAX_NS 1000000000LLU 

int main(void) { 
    unsigned int a = 4294967295; // type may remain unsigned 
    unsigned int b = 32 ;   // type may remain unsigned 

    unsigned long long c = ((b * MAX_NS)/a); 
    printf("%llu",c); 
} 

En variante, le câble coaxial multiplication en douceur en multipliant par 1ull. En général, évitez de couler comme dans (unsigned long long) b * MAX_NS. Pratique rampante de coulée étonnamment parfois se rétrécit le calcul qui pourrait arriver ici à une date ultérieure avec uintmax_t b.

#define MAX_NS 1000000000 

int main(void) { 
    unsigned int a = 4294967295; // type may remain unsigned 
    unsigned int b = 32 ;   // type may remain unsigned 

    unsigned long long c = ((1ull * b * MAX_NS)/a); 
    printf("%llu",c); 
} 
+0

merci pour la réponse, mais notre matériel ne supporte que 32 bits, ne peut pas utiliser longtemps non signé .. –

+0

@GopalaKrishna Même un processeur 8 bits peut prendre en charge 'long unsigned long'. Un compilateur C conforme formera les instructions nécessaires pour réaliser des types 64 bits et des maths. Des exigences inhabituelles comme "utiliser uniquement des maths 32 bits" doivent figurer dans la publication _original_. – chux