Comment modifier double par sa plus petite augmentation

Quelque chose est cassé ou je ne comprends pas ce qui se passe?

static Ssortingng getRealBinary(double val) { long tmp = Double.doubleToLongBits(val); SsortingngBuilder sb = new SsortingngBuilder(); for (long n = 64; --n > 0; tmp >>= 1) if ((tmp & 1) == 0) sb.insert(0, ('0')); else sb.insert(0, ('1')); sb.insert(0, '[').insert(2, "] [").insert(16, "] [").append(']'); return sb.toSsortingng(); } public static void main(Ssortingng[] argv) { for (int j = 3; --j >= 0;) { double d = j; for (int i = 3; --i >= 0;) { d += Double.MIN_VALUE; System.out.println(d +getRealBinary(d)); } } } 

Avec sortie:

 2.0[1] [00000000000] [000000000000000000000000000000000000000000000000000] 2.0[1] [00000000000] [000000000000000000000000000000000000000000000000000] 2.0[1] [00000000000] [000000000000000000000000000000000000000000000000000] 1.0[0] [11111111110] [000000000000000000000000000000000000000000000000000] 1.0[0] [11111111110] [000000000000000000000000000000000000000000000000000] 1.0[0] [11111111110] [000000000000000000000000000000000000000000000000000] 4.9E-324[0] [00000000000] [000000000000000000000000000000000000000000000000001] 1.0E-323[0] [00000000000] [000000000000000000000000000000000000000000000000010] 1.5E-323[0] [00000000000] [000000000000000000000000000000000000000000000000011] 

L’idée générale est tout d’abord de convertir le double en sa représentation longue (en utilisant doubleToLongBits comme vous l’avez fait dans getRealBinary ), de l’incrémenter de 1, puis de convertir le nouveau long back en double qu’il représente via longBitsToDouble .

EDIT: Java (depuis la version 1.5) fournit Math.ulp(double) , ce que je suppose que vous pouvez utiliser pour calculer directement la valeur immédiatement supérieure, ainsi: x + Math.ulp(x) .

Les nombres en virgule flottante ne sont pas répartis uniformément sur la droite numérique, contrairement aux types entiers. Ils sont plus serrés près de 0 et très éloignés à l’approche de l’infini. Par conséquent, aucune constante ne peut être ajoutée à un nombre à virgule flottante pour atteindre le prochain nombre à virgule flottante.

Votre code n’est pas bien formé. Vous essayez d’append la valeur double minimale et attendez-vous à ce que le résultat soit différent de la valeur d’origine. Le problème est que double.MinValue est si petit que le résultat est arrondi et n’est pas affecté.

Lecture suggérée: http://en.wikipedia.org/wiki/Machine_epsilon

Dans l’article de Wikipedia, il y a aussi le code Java. Epsilon est par définition le plus petit nombre tel que (X + eps * X! = X), et eps * X est appelé “relatif-epsilon”

Depuis Java 1.8, java.lang.Math.nextUp(double) fait exactement ce que vous voulez. Il y a aussi l’opposé java.lang.Math.nextDown(double) .

Si vous souhaitez utiliser la classe BigDecimal, il existe également la méthode BigDecimal.ulp() .