Roh*_*nga 45 c++ floating-point bitwise-operators genetic-algorithm
我试过这个:
float a = 1.4123;
a = a & (1 << 3);
Run Code Online (Sandbox Code Playgroud)
我得到一个编译错误,说操作数&不能是float类型.
当我做:
float a = 1.4123;
a = (int)a & (1 << 3);
Run Code Online (Sandbox Code Playgroud)
我让程序运行.唯一的事情是按位操作是在舍入后获得的数字的整数表示上完成的.
以下也是不允许的.
float a = 1.4123;
a = (void*)a & (1 << 3);
Run Code Online (Sandbox Code Playgroud)
我不明白为什么int可以投,void*但不是float.
我这样做是为了解决Stack Overflow问题中描述的问题如何使用遗传算法求解线性方程?.
AnT*_*AnT 73
在语言层面,没有"对浮点数进行按位运算"这样的事情.C/C++中的按位运算用于数字的值表示.并且在C/C++中没有定义浮点数的值表示.浮点数在值表示级别没有位,这就是为什么不能对它们应用按位运算的原因.
您所能做的就是分析浮点数占用的原始内存的位内容.为此,您需要使用下面建议的union或(等效地,仅在C++中)将浮点对象重新解释为对象数组unsigned char,如
float f = 5;
unsigned char *c = reinterpret_cast<unsigned char *>(&f);
// inspect memory from c[0] to c[sizeof f - 1]
Run Code Online (Sandbox Code Playgroud)
并且,请不要尝试将float对象重新解释为int对象,正如其他答案所暗示的那样.这没有多大意义,这是非法的,并且不能保证在优化中遵循严格别名规则的编译器中工作.在C++中检查内存内容的唯一合法方法是将其重新解释为数组[signed/unsigned] char.
另请注意,从技术上讲,您不能保证系统上的浮点表示是IEEE754(尽管在实践中它是除非您明确允许它不存在,然后仅针对-0.0,±无穷大和NaN).
mob*_*mob 17
如果您尝试更改浮点表示中的位,您可以执行以下操作:
union fp_bit_twiddler {
float f;
int i;
} q;
q.f = a;
q.i &= (1 << 3);
a = q.f;
Run Code Online (Sandbox Code Playgroud)
正如AndreyT指出的那样,访问这样的联合会调用未定义的行为,编译器可能会长出武器并扼杀你.做他的建议而不是.
float a = 1.4123;
unsigned int* inta = reinterpret_cast<unsigned int*>(&a);
*inta = *inta & (1 << 3);
Run Code Online (Sandbox Code Playgroud)
看看下面的内容.灵感来自快速反平方根:
#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;
}
Run Code Online (Sandbox Code Playgroud)
您可以解决严格别名规则,并对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);
Run Code Online (Sandbox Code Playgroud)