Вы можете использовать pkgutil.walk_packages
:
from pkgutil import walk_packages
possible_packages = [module for _, module, _ in walk_packages()]
На уровне языка не существует такой вещи, как «побитовые операции с числами с плавающей запятой». Побитовые операции в C / C ++ работают с представлением числа в виде значений. А представление значений чисел с плавающей запятой не определено в C / C ++. Числа с плавающей запятой не имеют битов на уровне представления значений, поэтому вы не можете применять к ним побитовые операции.
Все, что вы можете сделать, это проанализировать битовое содержимое необработанной памяти, занятой числами с плавающей запятой. номер точки. Для этого вам нужно либо использовать объединение, как предложено ниже, либо (эквивалентно и только в C ++) переинтерпретировать объект с плавающей запятой как массив объектов unsigned char
, как в
float f = 5;
unsigned char *c = reinterpret_cast<unsigned char *>(&f);
// inspect memory from c[0] to c[sizeof f - 1]
И, пожалуйста, не Не пытайтесь переинтерпретировать объект float
как объект int
, как предлагают другие ответы. В этом нет особого смысла, это незаконно и не гарантируется, что это будет работать в компиляторах, которые следуют правилам строгого псевдонима при оптимизации. Единственный законный способ проверить содержимое памяти в C ++ - интерпретировать его как массив [подписанный / беззнаковый] char
.
Также обратите внимание, что технически вам не гарантируется, что представление с плавающей запятой на вашем система соответствует стандарту IEEE754 (хотя на практике это так, если вы явно не разрешите этому не быть, и то только в отношении -0,0, ± бесконечность и NaN).
Можно работать приблизительно строго искажающее правило и выполнить битовые операции на float
каламбуривший типом как uint32_t
(если реализация определяет его, который большинство делает) без неопределенного поведения при помощи memcpy()
:
float a = 1.4123f;
uint32_t b;
std::memcpy(&b, &a, 4);
// perform bitwise operation
b &= 1u << 3;
std::memcpy(&a, &b, 4);
Обратите внимание на следующее. На основе быстрого обратного квадратного корня:
#include <iostream>
using namespace std;
int main()
{
float x, td = 2.0;
int ti = *(int*) &td;
cout << "Cast int: " << ti << endl;
ti = ti>>4;
x = *(float*) &ti;
cout << "Recast float: " << x << endl;
return 0;
}
@mobrule:
Лучше:
#include <stdint.h>
...
union fp_bit_twiddler {
float f;
uint32_t u;
} q;
/* mutatis mutandis ... */
Для эти значения int, вероятно, подойдут, но как правило, вы должны использовать целые числа без знака для сдвига битов, чтобы избежать эффектов арифметических сдвигов. А также uint32_t будет работать даже в системах, чьи int не являются 32-битными.
Если вы пытаетесь изменить биты в представлении с плавающей запятой, вы можете сделать что-то вроде этого:
union fp_bit_twiddler {
float f;
int i;
} q;
q.f = a;
q.i &= (1 << 3);
a = q.f;
Как отмечает AndreyT, доступ к подобному объединению вызывает неопределенное поведение, а компилятор мог отрастить руки и задушить вас. Вместо этого сделайте то, что он предлагает.
float a = 1.4123;
unsigned int* inta = reinterpret_cast<unsigned int*>(&a);
*inta = *inta & (1 << 3);