#java #bit-manipulation #bitwise-operators #ieee-754
#java #битовая манипуляция #побитовые операторы #ieee-754
Вопрос:
Я знаю, что это звучит как вопрос, который задавался ранее, но в моем случае меня просят выполнить некоторую побитовую логику для значения int32 и интерпретировать его как значение с плавающей запятой, не преобразовывая значение в значение с плавающей запятой, а интерпретируя двоичное значение, связанное с ним, как значение с плавающей запятой и находя значащие биты (также известные как мантисса) в наборе. Я использую стандарт IEE-754 для преобразования.
Инструкции:
«Используйте битовую маску для выделения значащих цифр, затем используйте цикл для перебора каждой цифры, сдвигая по мере необходимости, чтобы получить их в позиции LSB, и умножая на соответствующую степень 2. Результатом будет значение с плавающей точкой без показателя степени. Не забудьте включить «скрытый» бит! Рассмотрим цикл с обратным отсчетом — обработайте его тщательно, и это позволит вам начать с LSB и проложить свой путь к MSB. «
Исходя из моего понимания этого, я создал эту мерзость
public static float decodeSignificantDigits(int value) {
int mask = 0x007FFFFF;
int significantBits = value amp; mask;
float significantDigits = 0;
for (int i = -23; i <= 0; i ) {
if (i != 0) {
significantDigits = (significantBits >> 1) * Math.pow(2, i);
} else {
significantDigits = 1 * Math.pow(2, i);
}
}
System.out.println(significantDigits);
return significantDigits;
}
Я думаю, что я на правильном пути, но я просто не могу представить, как заставить это работать правильно.
Основная идея состоит в том, чтобы пройти следующие тесты:
@Test
void testWhenAllOnes() {
int bits = 0b00000000011111111111111111111111;
int bitsWithExpoentZero = 0b00111111111111111111111111111111;
assertEquals(Float.intBitsToFloat(bitsWithExpoentZero), FloatDecoder.decodeSignificantDigits(bits), TOL);
}
@Test
void testWhenMsbOfSignificantDigitsIsOneRestZeroes() {
int bits = 0b00000000010000000000000000000000;
int bitsWithExpoentZero = 0b00111111110000000000000000000000;
assertEquals(Float.intBitsToFloat(bitsWithExpoentZero), FloatDecoder.decodeSignificantDigits(bits), TOL);
}
@Test
void testWhenLsbOfSignificantDigitsIsOneRestZeroes() {
int bits = 0b00000000000000000000000000000001;
int bitsWithExpoentZero = 0b00111111100000000000000000000001;
assertEquals(Float.intBitsToFloat(bitsWithExpoentZero), FloatDecoder.decodeSignificantDigits(bits), TOL);
}
Мне также сообщили, чтобы я не использовал Integer.toBinaryString() для моего решения.
Комментарии:
1.
Math.pow(2, i)
не делайте этого. Используйте1 << i
вместо2. Лучше, некоторые из моих тестов работают сейчас. Но почему это работает?
3. Потому что это на 100% точно, а FP — нет.
4. Конечно, это очевидно, но я имею в виду, как работает сдвиг от 1 до n количества битов? Я уверен, что это глупый вопрос для кого-то опытного, но я не опытный.