Je rédigeais un programme en C ++ pour trouver toutes les solutions d' un b = c , où a , b et c ensemble utiliser tous les chiffres 0-9 exactement une fois. Le programme a bouclé sur les valeurs de a et b , et il a exécuté une routine de comptage de chiffres à chaque fois sur a , b et a b pour vérifier si la condition des chiffres était satisfaite.
Cependant, les solutions parasites peuvent être générées lors d' un b déborde la limite entière. J'ai fini par vérifier cela en utilisant du code comme:
unsigned long b, c, c_test;
...
c_test=c*b; // Possible overflow
if (c_test/b != c) {/* There has been an overflow*/}
else c=c_test; // No overflow
Existe-t-il un meilleur moyen de tester le débordement? Je sais que certaines puces ont un indicateur interne qui est défini lorsqu'un débordement se produit, mais je ne l'ai jamais vu accessible via C ou C ++.
Attention, le débordement signé int
est un comportement indéfini en C et C ++ , et vous devez donc le détecter sans le provoquer réellement. Pour le débordement int signé avant l'ajout, voir Détection d'un débordement signé dans C / C ++ .
la source
-ftrapv
fera générer un débordement d'entier SIGABRT sur (signé). Voyez ici .clz
instruction ou la__clz(unsigned)
fonction pour déterminer le rang du nombre (où se trouve son bit le plus élevé). Comme je ne sais pas si cela est disponible sur x86 ou x64, je suppose que ce n'est pas le cas et je dis que trouver le bit le plus significatif prendra au pire deslog(sizeof(int)*8)
instructions.Réponses:
Je vois que vous utilisez des entiers non signés. Par définition, en C (je ne connais pas C ++), l'arithmétique non signée ne déborde pas ... donc, au moins pour C, votre point est sans objet :)
Avec les entiers signés, une fois qu'il y a eu débordement, un comportement non défini (UB) s'est produit et votre programme peut faire n'importe quoi (par exemple: rendre les tests non concluants).
Pour créer un programme conforme, vous devez tester le débordement avant de générer ledit débordement. La méthode peut également être utilisée avec des entiers non signés:
Pour la division (à l'exception du cas spécial
INT_MIN
et-1
), il n'y a aucune possibilité d'aller au-dessusINT_MIN
ouINT_MAX
.la source
x >= 0
-x > 0
suffira (six == 0
, alorsx + a
ne peut pas déborder pour des raisons évidentes).if ((a < INT_MIN / x))
le test est trop tard. Unif (x == -1)
test est d'abord nécessaire.Il existe un moyen de déterminer si une opération est susceptible de déborder, en utilisant les positions des bits les plus significatifs dans les opérandes et un peu de connaissances de base en mathématiques binaires.
De plus, deux opérandes quelconques donneront (au plus) un bit de plus que le bit le plus élevé du plus grand opérande. Par exemple:
Pour la multiplication, deux opérandes quelconques donneront (au plus) la somme des bits des opérandes. Par exemple:
De même, vous pouvez estimer la taille maximale du résultat
a
à la puissance deb
ceci:(Remplacez le nombre de bits pour votre entier cible, bien sûr.)
Je ne suis pas sûr du moyen le plus rapide pour déterminer la position du bit le plus élevé d'un nombre, voici une méthode de force brute:
Ce n'est pas parfait, mais cela vous donnera une bonne idée si deux nombres peuvent déborder avant de faire l'opération. Je ne sais pas si ce serait plus rapide que de simplement vérifier le résultat comme vous l'avez suggéré, à cause de la boucle dans la
highestOneBitPosition
fonction, mais cela pourrait (surtout si vous saviez combien de bits étaient dans les opérandes au préalable).la source
log2
, mais cela ne serait pas nécessairement aussi évident pour quelqu'un qui n'a pas de formation mathématique.multiplication_is_safe
0x8000 * 0x10000
débordement (les positions des bits sont 16 + 17 = 33, ce qui est > 32 ), bien que ce ne soit pas le cas, car cela tient0x8000 * 0x10000 = 0x80000000
évidemment toujours dans un int 32 bits non signé. Ce n'est qu'un exemple parmi d'autres pour lesquels ce code ne fonctionne pas.0x8000 * 0x10001
, ...0x8000 * 0x10000
n'est pas «sûr», selon cette définition, même si cela se passe bien.Clang 3.4+ et GCC 5+ offrent des fonctionnalités arithmétiques vérifiées. Ils offrent une solution très rapide à ce problème, en particulier par rapport aux contrôles de sécurité de test de bits.
Pour l'exemple de la question de OP, cela fonctionnerait comme ceci:
La documentation de Clang ne spécifie pas si
c_test
contient le résultat de débordement en cas de débordement, mais la documentation de GCC indique que c'est le cas. Étant donné que ces deux aiment être__builtin
compatibles, il est probablement sûr de supposer que c'est aussi ainsi que fonctionne Clang.Il existe
__builtin
pour chaque opération arithmétique qui peut déborder (addition, soustraction, multiplication), avec des variantes signées et non signées, pour les tailles int, les tailles longues et les tailles longues et longues. La syntaxe du nom est__builtin_[us](operation)(l?l?)_overflow
:u
pour non signé ous
pour signé ;add
,sub
oumul
;l
suffixe signifie que les opérandes sontint
s; unl
moyenlong
; deuxl
s signifientlong long
.Donc, pour un ajout d'entier long signé signé, ce serait
__builtin_saddl_overflow
. La liste complète se trouve sur la page de documentation de Clang .GCC 5+ et Clang offrent en outre builtins supérieure à 3,8 génériques qui fonctionnent sans préciser le type des valeurs:
__builtin_add_overflow
,__builtin_sub_overflow
et__builtin_mul_overflow
. Ils fonctionnent également sur des types plus petits queint
.Les valeurs intégrées sont inférieures à ce qui est le mieux pour la plateforme. Sur x86, ils vérifient les indicateurs de portage, de débordement et de signature.
Le fichier cl.exe de Visual Studio n'a pas d'équivalents directs. Pour les ajouts et soustractions non signés, notamment
<intrin.h>
vous permettra d'utiliseraddcarry_uNN
etsubborrow_uNN
(où NN est le nombre de bits, commeaddcarry_u8
ousubborrow_u64
). Leur signature est un peu obtuse:c_in
/b_in
est l'indicateur carry / borrow en entrée et la valeur de retour est le carry / borrow en sortie. Il ne semble pas avoir d'équivalents pour les opérations signées ou les multiplications.Sinon, Clang pour Windows est maintenant prêt pour la production (assez bon pour Chrome), ce qui pourrait également être une option.
la source
__builtin_sub_overflow
n'est certainement pas dans Clang 3.4.__builtin_add_overflow
amis devraient déjà être disponibles sur Clang 3.8.Certains compilateurs donnent accès à l'indicateur de dépassement d'entier dans le processeur que vous pouvez ensuite tester, mais ce n'est pas standard.
Vous pouvez également tester la possibilité de débordement avant d'effectuer la multiplication:
la source
b == ULONG_MAX / a
? Ensuite, il peut encore s'adapter, étant donné que sea
diviseULONG_MAX
sans résidu.Avertissement: GCC peut optimiser une vérification de dépassement lors de la compilation avec
-O2
. L'option-Wall
vous donnera un avertissement dans certains cas commemais pas dans cet exemple:
Le seul moyen sûr est de vérifier le débordement avant qu'il ne se produise, comme décrit dans le document CERT , et ce serait incroyablement fastidieux à utiliser systématiquement.
La compilation avec
-fwrapv
résout le problème, mais désactive certaines optimisations.Nous avons désespérément besoin d'une meilleure solution. Je pense que le compilateur devrait émettre un avertissement par défaut lors de la réalisation d'une optimisation qui repose sur un débordement qui ne se produit pas. La situation actuelle permet au compilateur d'optimiser un contrôle de débordement, ce qui est inacceptable à mon avis.
la source
for(int k = 0; k < 5; k++) {...}
devrait lancer un avertissement?k
peuvent être facilement déterminées au moment de la compilation. Le compilateur n'a pas à faire d'hypothèses.n
est inférieure à 32, avant d'émettre une instruction de décalage qui utilise uniquement les 5 bits inférieurs den
?Clang prend désormais en charge les vérifications de dépassement dynamique pour les entiers signés et non signés. Voir le commutateur -fsanitize = entier . Pour l'instant, c'est le seul compilateur C ++ avec une vérification de débordement dynamique entièrement prise en charge à des fins de débogage.
la source
Je vois que beaucoup de gens ont répondu à la question sur le débordement, mais je voulais aborder son problème d'origine. Il a dit que le problème était de trouver un b = c tel que tous les chiffres soient utilisés sans répétition. Ok, ce n'est pas ce qu'il a demandé dans ce post, mais je pense toujours qu'il était nécessaire d'étudier la limite supérieure du problème et de conclure qu'il n'aurait jamais besoin de calculer ou de détecter un débordement (note: je ne suis pas compétent en mathématiques, j'ai donc fait cela étape par étape, mais le résultat final était si simple que cela pourrait avoir une formule simple).
Le point principal est que la limite supérieure que le problème requiert pour a, b ou c est 98.765.432. Quoi qu'il en soit, en commençant par diviser le problème dans les parties triviales et non triviales:
Il suffit maintenant de montrer qu'aucune autre solution n'est possible et que seules les permutations sont valides (et alors le code pour les imprimer est trivial). Nous revenons à la limite supérieure. En fait, la limite supérieure est c ≤ 98,765,432. C'est la limite supérieure car c'est le plus grand nombre à 8 chiffres (10 chiffres au total moins 1 pour chaque a et b). Cette limite supérieure n'est valable que pour c car les limites pour a et b doivent être beaucoup plus faibles en raison de la croissance exponentielle, comme nous pouvons le calculer, variant b de 2 à la limite supérieure:
Remarquez, par exemple la dernière ligne: il est dit que 1,97 ^ 27 ~ 98M. Ainsi, par exemple, 1 ^ 27 == 1 et 2 ^ 27 == 134.217.728 et ce n'est pas une solution car il a 9 chiffres (2> 1,97 donc il est en fait plus grand que ce qui devrait être testé). Comme on peut le voir, les combinaisons disponibles pour tester a et b sont vraiment petites. Pour b == 14, nous devons essayer 2 et 3. Pour b == 3, nous commençons à 2 et nous arrêtons à 462. Tous les résultats sont accordés pour être inférieurs à ~ 98M.
Maintenant, testez toutes les combinaisons ci-dessus et recherchez celles qui ne répètent aucun chiffre:
Aucun d'entre eux ne correspond au problème (ce qui peut également être constaté par l'absence de «0», «1», ..., «9»).
L'exemple de code qui le résout suit. Notez également que cela est écrit en Python, non pas parce qu'il a besoin d'entiers de précision arbitraires (le code ne calcule rien de plus de 98 millions), mais parce que nous avons découvert que le nombre de tests est si petit que nous devrions utiliser un langage de haut niveau pour utiliser ses conteneurs et bibliothèques intégrés (notez également: le code a 28 lignes).
la source
Voici une solution "non portable" à la question. Les processeurs Intel x86 et x64 ont le soi-disant registre EFLAGS , qui est rempli par le processeur après chaque opération arithmétique entière. Je vais sauter une description détaillée ici. Les drapeaux concernés sont le drapeau "Overflow" (masque 0x800) et le drapeau "Carry" (masque 0x1). Pour les interpréter correctement, il faut considérer si les opérandes sont de type signé ou non signé.
Voici un moyen pratique de vérifier les indicateurs de C / C ++. Le code suivant fonctionnera sur Visual Studio 2005 ou plus récent (32 et 64 bits), ainsi que sur GNU C / C ++ 64 bits.
Si les opérandes étaient multipliés sans débordement, vous obtiendriez une valeur de retour de 0
query_intel_eflags(0x801)
, c'est-à-dire que ni les indicateurs de report ni de débordement ne sont définis. Dans l'exemple de code fourni de main (), un débordement se produit et les deux indicateurs sont définis sur 1. Cette vérification n'implique aucun calcul supplémentaire, elle devrait donc être assez rapide.la source
Si vous avez un type de données qui est plus grand que celui que vous souhaitez tester (disons que vous faites un ajout 32 bits et que vous avez un type 64 bits), cela détectera si un débordement s'est produit. Mon exemple est pour un ajout 8 bits. Mais il peut être étendu.
Il est basé sur les concepts expliqués sur cette page: http://www.cs.umd.edu/class/spring2003/cmsc311/Notes/Comb/overflow.html
Pour un exemple 32 bits,
0xFF
devient0xFFFFFFFF
et0x80
devient0x80000000
etuint16_t
devient finalement auint64_t
.REMARQUE : cela attrape les débordements d'addition / soustraction entiers, et j'ai réalisé que votre question implique la multiplication. Dans ce cas, la division est probablement la meilleure approche. C'est généralement un moyen que les
calloc
implémentations s'assurent que les paramètres ne débordent pas car ils sont multipliés pour obtenir la taille finale.la source
Le moyen le plus simple est de convertir vos
unsigned long
s enunsigned long long
s, de faire votre multiplication et de comparer le résultat à 0x100000000LL.Vous constaterez probablement que c'est plus efficace que de faire la division comme vous l'avez fait dans votre exemple.
Oh, et cela fonctionnera à la fois en C et C ++ (comme vous avez marqué la question avec les deux).
Je viens de jeter un œil au manuel de la glibc . Il y a une mention d'un piège de débordement d'entier (
FPE_INTOVF_TRAP
) dans le cadre deSIGFPE
. Ce serait idéal, en dehors des méchants morceaux du manuel:Un peu dommage vraiment.
la source
ULONG_MAX
ce qui est plus facile à taper et plus portable que le codage en dur0x100000000
.long
etlong long
sont de la même taille (par exemple sur de nombreux compilateurs 64 bits).Voici un moyen très rapide de détecter les débordements pour au moins les ajouts, ce qui pourrait donner une avance pour la multiplication, la division et la puissance de.
L'idée est qu'exactement parce que le processeur laissera simplement la valeur revenir à zéro et que C / C ++ doit être extrait de n'importe quel processeur spécifique, vous pouvez:
Cela garantit à la fois que si un opérande est nul et que l'autre ne l'est pas, le débordement ne sera pas faussement détecté et sera beaucoup plus rapide que beaucoup d'opérations NOT / XOR / AND / test comme suggéré précédemment.
Comme indiqué, cette approche, bien que meilleure que d'autres méthodes plus élaborées, est toujours optimisable. Ce qui suit est une révision du code d'origine contenant l'optimisation:
Un moyen plus efficace et moins cher de détecter un débordement de multiplication est:
Il en résulte soit UINT32_MAX en cas de débordement, soit le résultat de la multiplication. C'est un comportement strictement indéfini de permettre à la multiplication de se poursuivre pour les entiers signés dans ce cas.
la source
x+y>=256
etvalue=x+y-256
. Parce quey<256
toujours vrai, (y-256) est négatif et doncvalue < x
toujours vrai. La preuve pour le cas non débordant est assez similaire.uint32_t x[N], y[N], z[N], carry=0; for (int i = 0; i < N; i++) { z[i] = x[i] + y[i] + carry; carry = z[i] < (x[i] | y[i]); }
Si vous ne saisissez pasor
les valeurs, vous ne pourrez pas faire la distinction entre un opérande et le bit de retenue étant nul et un opérande étant0xffffffff
et le bit de retenue étant un.Vous ne pouvez pas accéder à l'indicateur de débordement depuis C / C ++.
Certains compilateurs vous permettent d'insérer des instructions d'interruption dans le code. Sur GCC, l'option est
-ftrapv
.La seule chose portable et indépendante du compilateur que vous pouvez faire est de vérifier vous-même les débordements. Tout comme vous l'avez fait dans votre exemple.
Cependant,
-ftrapv
semble ne rien faire sur x86 en utilisant le dernier GCC. Je suppose que c'est un reste d'une ancienne version ou spécifique à une autre architecture. Je m'attendais à ce que le compilateur insère un opcode INTO après chaque ajout. Malheureusement, cela ne fonctionne pas.la source
Pour les entiers non signés, vérifiez simplement que le résultat est inférieur à l'un des arguments:
Pour les entiers signés, vous pouvez vérifier les signes des arguments et du résultat.
Les entiers de signes différents ne peuvent pas déborder et les entiers du même signe ne débordent que si le résultat est d'un signe différent:
la source
char result = (char)127 + (char)3;
serait -126; plus petit que les deux opérandes.J'avais besoin de répondre à cette même question pour les nombres à virgule flottante, où le masquage et le décalage des bits ne semblent pas prometteurs. L'approche sur laquelle je me suis installé fonctionne pour les nombres signés et non signés, entiers et à virgule flottante. Il fonctionne même s'il n'y a pas de type de données plus volumineux à promouvoir pour des calculs intermédiaires. Ce n'est pas le plus efficace pour tous ces types, mais parce qu'il fonctionne pour tous, il vaut la peine d'être utilisé.
Test de dépassement signé, addition et soustraction:
Obtenez les constantes qui représentent les valeurs les plus grandes et les plus petites possibles pour le type, MAXVALUE et MINVALUE.
Calculez et comparez les signes des opérandes.
une. Si l'une des valeurs est nulle, ni l'addition ni la soustraction ne peuvent déborder. Ignorez les tests restants.
b. Si les signes sont opposés, l'addition ne peut pas déborder. Ignorez les tests restants.
c. Si les signes sont les mêmes, la soustraction ne peut pas déborder. Ignorez les tests restants.
Testez le débordement positif de MAXVALUE.
une. Si les deux signes sont positifs et MAXVALUE - A <B, l'addition débordera.
b. Si le signe de B est négatif et MAXVALUE - A <-B, alors la soustraction débordera.
Testez le débordement négatif de MINVALUE.
une. Si les deux signes sont négatifs et MINVALUE - A> B, l'addition débordera.
b. Si le signe de A est négatif et MINVALUE - A> B, la soustraction débordera.
Sinon, pas de débordement.
Test de dépassement signé, multiplication et division:
Obtenez les constantes qui représentent les valeurs les plus grandes et les plus petites possibles pour le type, MAXVALUE et MINVALUE.
Calculez et comparez les magnitudes (valeurs absolues) des opérandes à un. (Ci-dessous, supposons que A et B sont ces grandeurs, pas les originaux signés.)
une. Si l'une des valeurs est nulle, la multiplication ne peut pas déborder et la division donnera zéro ou une infinité.
b. Si l'une ou l'autre valeur est une, la multiplication et la division ne peuvent pas déborder.
c. Si la grandeur d'un opérande est inférieure à un et que l'autre est supérieur à un, la multiplication ne peut pas déborder.
ré. Si les grandeurs sont toutes deux inférieures à un, la division ne peut pas déborder.
Testez le débordement positif de MAXVALUE.
une. Si les deux opérandes sont supérieurs à un et MAXVALUE / A <B, la multiplication débordera.
b. Si B est inférieur à un et MAXVALUE * B <A, la division débordera.
Sinon, pas de débordement.
Remarque: le débordement minimum de MINVALUE est géré par 3, car nous avons pris des valeurs absolues. Cependant, si ABS (MINVALUE)> MAXVALUE, alors nous aurons de rares faux positifs.
Les tests de sous-dépassement sont similaires, mais impliquent EPSILON (le plus petit nombre positif supérieur à zéro).
la source
1.0e-200 / 1.0e200
serait un exemple de sous-dépassement réel, en supposant que l'IEEE double. Le terme correct ici, au lieu de cela, est débordement négatif. </pedantic>1/INT_MAX
pourrait bien être considéré comme sous-dépassé, mais le langage impose simplement la troncature à zéro.Le CERT a développé une nouvelle approche pour détecter et signaler les dépassements d'entiers signés, les enveloppes d'entiers non signés et la troncature d'entiers en utilisant le modèle d'entier "comme si" à plage infinie (AIR). Le CERT a publié un rapport technique décrivant le modèle et produit un prototype fonctionnel basé sur GCC 4.4.0 et GCC 4.5.0.
Le modèle AIR entier produit une valeur équivalente à celle qui aurait été obtenue à l'aide d'entiers à plage infinie ou entraîne une violation de contrainte d'exécution. Contrairement aux modèles d'entiers précédents, les entiers AIR ne nécessitent pas d'interruptions précises et, par conséquent, ne cassent ni n'inhibent la plupart des optimisations existantes.
la source
Un autre outil intéressant est IOC: An Integer Overflow Checker for C / C ++ .
Il s'agit d'un compilateur Clang patché , qui ajoute des vérifications au code au moment de la compilation.
Vous obtenez une sortie ressemblant à ceci:
la source
Une autre variante d'une solution, utilisant le langage d'assemblage, est une procédure externe. Cet exemple de multiplication d'entiers non signés utilisant g ++ et fasm sous Linux x64.
Cette procédure multiplie deux arguments entiers non signés (32 bits) (selon la spécification pour amd64 (section 3.2.3 Passage de paramètres ).
(registres edi et esi dans mon code)) et renvoie le résultat ou 0 si un débordement s'est produit.
Tester:
Liez le programme avec le fichier objet asm. Dans mon cas, dans Qt Creator , ajoutez-le à
LIBS
un fichier .pro.la source
Calculez les résultats avec des doubles. Ils ont 15 chiffres significatifs. Votre exigence a une limite supérieure rigide sur c de 10 8 - elle peut avoir au plus 8 chiffres. Par conséquent, le résultat sera précis s'il est à portée, et il ne débordera pas autrement.
la source
Essayez cette macro pour tester le bit de débordement des machines 32 bits (adapté la solution d'Angel Sinigersky)
Je l'ai défini comme une macro car sinon le bit de débordement aurait été écrasé.
Ensuite, une petite application avec le segment de code ci-dessus:
la source
_MSC_VER
bien que les compilations MS rejetteront toutes le code).Catching Integer Overflows in C indique une solution plus générale que celle discutée par CERT (elle est plus générale en termes de types gérés), même si elle nécessite des extensions GCC (je ne sais pas dans quelle mesure elles sont largement prises en charge).
la source
Je ne suis pas d'accord avec ça. Vous pouvez écrire un langage d'assemblage en ligne et utiliser une
jo
instruction (saut de débordement) en supposant que vous êtes sur x86 pour intercepter le débordement. Bien sûr, votre code ne serait plus portable sur d'autres architectures.Regardez
info as
etinfo gcc
.la source
Pour développer la réponse de Head Geek, il existe un moyen plus rapide de faire le
addition_is_safe
;Cela utilise l'architecture de la machine en toute sécurité, dans la mesure où les entiers non signés 64 bits et 32 bits fonctionneront toujours correctement. Fondamentalement, je crée un masque qui masquera tout sauf le bit le plus significatif. Ensuite, je masque les deux entiers, et si aucun d'entre eux n'a ce bit défini, l'addition est sûre.
Ce serait encore plus rapide si vous pré-initialisez le masque dans un constructeur, car il ne change jamais.
la source
UINT_MAX + 1
. Après le masquage,a
le bit élevé sera défini, mais1
deviendra nul et donc la fonction reviendratrue
, l'addition est sûre - mais vous vous dirigez directement vers le débordement.mozilla::CheckedInt<T>
fournit des mathématiques entières vérifiées par débordement pour le type entierT
(en utilisant les caractéristiques intrinsèques du compilateur sur clang et gcc selon les disponibilités). Le code est sous MPL 2.0 et dépend de trois (IntegerTypeTraits.h
,Attributes.h
etCompiler.h
) autres en-têtes de bibliothèque non standard uniquement en-tête ainsi que des mécanismes d'assertion spécifiques à Mozilla . Vous souhaiterez probablement remplacer le mécanisme d'assertion si vous importez le code.la source
Réponse de MSalter est une bonne idée.
Si le calcul de l'entier est requis (pour plus de précision), mais qu'une virgule flottante est disponible, vous pouvez faire quelque chose comme:
la source
(c * log(a) < max_log)
, oùconst double max_log = log(UINT_MAX)
Le jeu d'instructions x86 comprend une instruction de multiplication non signée qui stocke le résultat dans deux registres. Pour utiliser cette instruction de C, on peut écrire le code suivant dans un programme 64 bits (GCC):
Pour un programme 32 bits, il faut rendre le résultat 64 bits et les paramètres 32 bits.
Une alternative consiste à utiliser intrinsèque dépendant du compilateur pour vérifier le registre des indicateurs. La documentation GCC pour le débordement intrinsèque peut être trouvée dans 6.56 Fonctions intégrées pour effectuer l'arithmétique avec la vérification du débordement .
la source
__uint128
pour éviter un débordement signé et un décalage à droite d'une valeur négative.la source
Une manière propre de le faire serait de remplacer tous les opérateurs (+ et * en particulier) et de vérifier un débordement avant d'effectuer les opérations.
la source
Cela dépend de l'utilisation que vous en faites. Pour effectuer une addition ou une multiplication DWORD longue non signée, la meilleure solution consiste à utiliser ULARGE_INTEGER.
ULARGE_INTEGER est une structure de deux DWORD. La valeur complète est accessible en tant que "QuadPart" tandis que le DWORD élevé est accessible en tant que "HighPart" et le DWORD faible est accessible en tant que "LowPart".
Par exemple:
la source
ULARGE_INTEGER
.Pour effectuer une multiplication non signée sans déborder de manière portable, les éléments suivants peuvent être utilisés:
la source
Le moyen simple de tester le débordement consiste à effectuer la validation en vérifiant si la valeur actuelle est inférieure à la valeur précédente. Par exemple, supposons que vous disposiez d'une boucle pour imprimer les puissances de 2:
L'ajout d'un débordement vérifiant la façon dont j'ai décrit les résultats dans ceci:
Il fonctionne pour les valeurs non signées ainsi que pour les valeurs signées positives et négatives.
Bien sûr, si vous vouliez faire quelque chose de similaire pour diminuer les valeurs au lieu d'augmenter les valeurs, vous renverseriez le
<=
signe pour le faire>=
, en supposant que le comportement de sous-dépassement est le même que le comportement de débordement. En toute honnêteté, c'est à peu près aussi portable que vous aurez sans accès à l'indicateur de débordement d'un processeur (et cela nécessiterait du code d'assemblage en ligne, ce qui rend votre code non portable dans toutes les implémentations de toute façon).la source