2015-05-13 2 views
5

например: 0.5 и 0.25 - сила 2, но 0.3 нет, также я знаю, проверяем, является ли целое число мощностью 2 простым, но как найти, если число равно 2, если число < 1?Как проверить, является ли число <1 мощностью 2?

public bool isPowerOf2(float number){ 
    if(number>1){ 
     //easy to write 
    }else if(number==1){ 
     return true; 
    }else{ 
     //hard to write 
    } 
} 
+1

isPowerOf2 (1/x) = isPowerOf2 (x). Однако я сомневаюсь, что число> 1 случай «легко писать» полезным способом –

+2

@Aakash Как это непонятно? «Легко проверить, является ли целое число в два раза, и как это сделать с нецелыми?» – immibis

+1

Вы можете написать их одинаково для всех чисел, кроме денонмов, но это, вероятно, использует другой трюк, чем вы имели в виду. – harold

ответ

7

Попробуйте это решение:

public boolean isPowerOf2(float number){ 
    if(number>1){ 
     //easy to write 
    }else if(number==1){ 
     return true; 
    }else if(number>0){ 
     return isPowerOf2(1.0f/number); 
    }else 
     return false; 
} 

По пути вы можете решить эту проблему, просто проверяя биты флоат двоичного представления:

public static boolean isPowerOfTwo(float i) { 
    int bits = Float.floatToIntBits(i); 
    if((bits & ((1 << 23)-1)) != 0) 
     return ((bits & (bits-1)) == 0); // denormalized number 
    int power = bits >>> 23; 
    return power > 0 && power < 255; // 255 = Infinity; higher values = negative numbers 
} 
+0

Вам также нужно проверить бит знака правильно? –

+0

Если вы имеете в виду решение бит, то оно уже проверено: 'power' включает знак и будет более 255 для отрицательных чисел (' 255' = 'Infinity'). –

+0

Да, очень умно :) –

0

Просто позвоните isPowerOf2(1.0/number); в else блоке. Он должен решить вашу проблему.

3

Хотя использование 1/x, скорее всего, будет работать нормально, можно было бы беспокоиться об ошибках округления.

Используйте Float.floatToRawIntBits(float). Вы, , вероятно, хотите проверить, что бит 22 включен, но биты 21-0 выключены (также бит знака должен быть 0). Это работает как с положительной, так и с отрицательной степенью 2. Действительная мощность находится в битах 30-23.

Приложение: если бит 21 выключен, но только один из бит 20-0 включен, он имеет мощность 2, как указано @anonymous. Существует хорошо известный трюк, чтобы быстро проверить, установлен ли ровно один бит, который вы наверняка найдете где-нибудь в Stack Overflow.

+0

Число может также быть степенью 2, если число положительно, показатель (смещенный) равен нулю, и в мантиссе точно установлен один бит. –

+0

Вы также должны заботиться о денормализованных числах. –

+0

Я знаю, что есть некоторые детали gory - спасибо за напоминания! – user949300

0

Java использует IEEE 754 для кодирования поплавков. Часть от битов 22 до 0 в двоичном кодировании представляет собой мантису (m). Если т имеет ровно одну 1, то поплавок является степенью 2.

http://introcs.cs.princeton.edu/java/91float/

(-1)^s × m × 2^(e - 127) 

знаковый бит (ы) (бит 31). Самый старший бит представляет знак числа (1 для отрицательного, 0 для положительного).

Экспоненциальное поле (e) (бит 30 - 23). Следующие 8 бит представляют экспоненту. По соглашению экспонента смещается на 127. Это означает, что для представления двоичного показателя 5 мы кодируем 127 + 5 = 132 в двоичном (10000100). Чтобы представить двоичный показатель -5, мы кодируем 127 - 5 = 122 в двоичном (01111010). Это соглашение является альтернативой нотации дополнений двух для представления отрицательных целых чисел.

Mantissa (m) (бит 22 - 0). Оставшиеся 23 бита представляют собой мантисс, нормализованные между 0,5 и 1. Эта нормализация всегда возможна, соответственно корректируя бинарный показатель. Двоичные фракции работают как десятичные дроби: 0.1101 представляет 1/2 + 1/4 + 1/16 = 13/16 = 0,8125. Не каждое десятичное число может быть представлено как двоичная дробь. Например, 1/10 = 1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 + ... В этом случае число 0,1 аппроксимируется ближайшей 23-битной двоичной фракцией 0,000110011001100110011 ... Используется еще одна оптимизация. Поскольку мантисса всегда начинается с 1, нет необходимости явно хранить этот скрытый бит.

Смежные вопросы