Vor der Suche nach der Methode Long.numberOfLeadingZeros(long i), war ich Casting Longs zu Doppel und Verwendung Math.getExponent(double d). Die Idee war, die doppelte Darstellung des langen zu finden, den Exponenten zu verwenden, um das höchste gesetzte Bit zu erhalten, und es von 64 zu subtrahieren, um die Anzahl der führenden Nullen zu erhalten.Java - führende Nullen in einer langen durch Konvertierung zu Doppel
Dies funktionierten meistens, aber ausgeschaltet war gelegentlich von 1. Die folgenden for-Schleife, das Problem zu markieren, wurde verwendet:
for (int i = 0; i < 64; i++) {
double max = Long.MAX_VALUE >>> i;
double min = Long.MIN_VALUE >>> i;
double neg = -1L >>> i;
System.out.format("Max: %-5d Min: %-5d -1: %-5d%n", Math.getExponent(dmax),
Math.getExponent(dmin), Math.getExponent(dneg));
}
mit dem wesentlichen Teil des Ausgangs:
...
Max: 55 Min: 55 -1: 56
Max: 54 Min: 54 -1: 55
Max: 52 Min: 53 -1: 54
Max: 51 Min: 52 -1: 52
Max: 50 Min: 51 -1: 51
...
Die longs mit allen gesetzten Bits sind um 1 über 2^52 ausgeschaltet. As this post explains, Ein Genauigkeitsverlust tritt aufgrund der Speicherung von 53+ signifikanten Bits in der 52-Bit-Mantisse auf. Ich habe jedoch Mühe zu verstehen, warum der Exponent betroffen ist.
Während ich diese Methode nicht mehr benutze, bin ich immer noch neugierig: Warum und unter welchen Umständen versagt diese Methode, die führenden Nullen lange zu finden?
Das macht Sinn. Nach dem Lesen Ihres Beitrags habe ich Werte größer als 2^53 - 1 gezwungen, ihre 11 niedrigstwertigen Bits zu löschen: 'value & = 0xFFFFFFFFFFFFFF700L;' vor der Umwandlung in ein Doppel, was das Runden überflüssig macht. Ich habe auch vergessen, dass die Mantisse das zusätzliche implizierte Bit hat. Danke für die ausführliche Antwort! –