Sommation sûre de débordement

13

Supposons que l'on me donne entiers de largeur fixe (c'est-à-dire qu'ils s'inscrivent dans un registre de largeur w ), a 1 , a 2 , a n tels que leur somme a 1 + a 2 + + a n = S s'inscrit également dans un registre de largeur w .nwa1,a2,ana1+a2++an=Sw

Il me semble que l'on peut toujours permuter les nombres à telle sorte que chaque somme de préfixe S i = b 1 + b 2 + + b i rentre également dans un registre de largeur w .b1,b2,bnSi=b1+b2++biw

Fondamentalement, la motivation est de calculer la somme sur des machines à registre à largeur fixe sans avoir à se soucier des débordements d'entiers à n'importe quel stade intermédiaire.S=Sn

Existe-t-il un algorithme rapide (de préférence linéaire) pour trouver une telle permutation (en supposant que les sont donnés comme un tableau d'entrée)? (ou dire si une telle permutation n'existe pas).ai

Aryabhata
la source
3
Suivi: détection du débordement dans la sommation - existe-t-il une méthode plus rapide qui prend en compte les caractéristiques typiques du processeur?
Gilles 'SO- arrête d'être méchant'
1
Utilisez simplement les registres de complément à deux et additionnez-les. Même s'il déborde au milieu, votre condition préalable garantit que les débordements s'annuleront et le résultat sera correct. : P
CodesInChaos
@CodeInChaos: Est-ce vraiment vrai?
Aryabhata
1
Je le pense. Vous travaillez essentiellement dans un groupe modulo 2 ^ n, où vous choisissez la représentation canonique de -2^(n-1)à 2^(n-1)-1. Bien sûr, cela nécessite un complément à deux et un comportement de débordement bien défini, mais dans un langage comme C #, cela devrait fonctionner.
CodesInChaos
@CodeInChaos: N'y a-t-il pas deux possibilités qui donnent le même reste modulo ? Vous dites essentiellement, indépendamment de l'ordre, que l'un d'eux ne peut jamais se produire. Ou est-ce que je manque quelque chose? 2n
Aryabhata

Réponses:

10

Stratégie
L'algorithme de temps linéaire suivant adopte la stratégie de vol stationnaire autour de , en choisissant des nombres positifs ou négatifs en fonction du signe de la somme partielle. Il pré-traite la liste des numéros; il calcule la permutation de l'entrée à la volée , tout en effectuant l'addition.0

Algorithme

  1. Partitionner en a deux listes, les éléments positifs P et les éléments négatifs M . Les zéros peuvent être filtrés.a1,,anPM
  2. Soit .Sum=0
  3. Bien que les deux listes ne soient pas vides
  4.       Si { S u m : = S u m + tête ( M ) ; M : = queue ( M ) ; }Sum>0Sum:=Sum+head(M)M:=tail(M)
  5.       else { ; P : = queue ( P ) ; }Sum:=Sum+head(P)P:=tail(P)
  6. Lorsque l' un des deux listes est vide, ajoutez le reste de la liste restante .S

Exactitude L'
exactitude peut être établie en utilisant un argument inductif simple sur la longueur de la liste des nombres.

Premièrement, prouver que si sont tous positifs (ou tous négatifs), et que leur somme ne provoque pas de débordement, alors les sommes de préfixe non plus. C'est simple.a1,,an

Deuxièmement, prouver que est dans les limites est un invariant de la boucle de l'algorithme. De toute évidence, cela est vrai lors de l'entrée dans la boucle, comme S u m = 0 . Maintenant, si S u m > 0 , l'ajout d'un nombre négatif dans les limites de S u m ne fait pas sortir S u m des limites. De même, lorsque S u m 0, l' addition d'un nombre positif qui se trouve dans les limites de la somme ne fait pas sortir S u m des limites. Ainsi, à la sortie de la boucle,SumSum=0Sum>0SumSumSum0Sum est dans les limites.Sum

Maintenant, le premier résultat peut être appliqué, et ensemble, ils sont suffisants pour prouver que la somme ne sort jamais des limites.

Dave Clarke
la source
Vers une implémentation efficace sur place, effectuez a) le partitionnement Quicksort (la variante à deux points) avec pivot implicite puis b) résumez, en déplaçant un pointeur chacun à travers la zone avec une réponse négative. nombres positifs. 0
Raphael