Comment ajouter deux valeurs long
en Java de sorte que si le résultat déborde, il est bloqué à la plage Long.MIN_VALUE
.. Long.MAX_VALUE
?Ajout saturé de deux valeurs Java «longues» signées
Pour ajouter ints, on peut effectuer l'arithmétique dans long
précision et jeter le résultat à un int
, par exemple:
int saturatedAdd(int x, int y) {
long sum = (long) x + (long) y;
long clampedSum = Math.max((long) Integer.MIN_VALUE,
Math.min(sum, (long) Integer.MAX_VALUE));
return (int) clampedSum;
}
ou
import com.google.common.primitives.Ints;
int saturatedAdd(int x, int y) {
long sum = (long) x + (long) y;
return Ints.saturatedCast(sum);
}
mais dans le cas de long
il n'y a type primitif plus grand qui peut contenir la somme intermédiaire (débloqué).
Depuis c'est Java, je ne peux pas utiliser inline assembly (en particulier de l'ESS instructions d'add saturés.)
Il peut être mis en œuvre à l'aide BigInteger
, par exemple
static final BigInteger bigMin = BigInteger.valueOf(Long.MIN_VALUE);
static final BigInteger bigMax = BigInteger.valueOf(Long.MAX_VALUE);
long saturatedAdd(long x, long y) {
BigInteger sum = BigInteger.valueOf(x).add(BigInteger.valueOf(y));
return bigMin.max(sum).min(bigMax).longValue();
}
cependant la performance est importante pour cette méthode est idéale (si utile pour les tests.)
Je ne sais pas si d'éviter peut ramification affecter de manière significative les performances en Java. Je suppose qu'il peut, mais je voudrais comparer les méthodes avec et sans branchement.
connexes: How to do saturating addition in C?
En fait, vous pouvez utiliser l'assemblage, à condition que vous l'enveloppiez dans JNI ou JNA. Ce serait génial de voir une performance-sage entre les solutions proposées. – janislaw