c - 在c中获取 float 的指数

标签 c numbers floating

很抱歉,如果已经有人问过这个问题,并且我已经看到了提取 float 指数的其他方法,但这就是给我的:

unsigned f2i(float f)
{
  union {
    unsigned i;
    float f;
  } x;
  x.i = 0;
  x.f = f;
  return x.i;
}

我无法理解这个 union 数据类型,因为最后的返回 x.i 不应该总是使 f2i 返回 0 吗?

此外,这种数据类型对什么应用程序有用?例如,假设我有一个函数:

int getexponent(float f){
}

此函数应该获取偏差为 127 的 float 的指数值。我已经找到了很多方法来实现此目的,但是如何操作 f2i 函数来实现此目的?

非常感谢任何指点!

更新!! 哇,几年后,这看起来微不足道。 对于那些可能感兴趣的人,这是该功能!

int getexponent(float f) {
    unsigned f2u(float f); 
	unsigned int ui = (f2u(f)>>23) & 0xff ;//shift over by 23 and compare to 0xff to get the exponent with the bias 
	int bias = 127;//initialized bias 
	if(ui == 0) return 1-bias; // special case 0
	else if(ui == 255) return 11111111; //special case infinity
	return ui - bias;
}

最佳答案

I'm having trouble understanding this union datatype

union 数据类型是程序员指示某个变量可以是多种不同类型之一的方法。 C11标准的措辞有点像“一个联盟最多包含一个成员”。它用于诸如逻辑上可能是这样或那样的参数之类的东西。例如,IP 地址可能是 IPv4 地址或 IPv6 地址,因此您可以按如下方式定义地址类型:

struct IpAddress
{
    bool isIPv6;
    union 
    {
        uint8_t v4[4];
        uint8_t v6[16];
    } bytes;
}

你会这样使用它:

struct IpAddress address = // Something
if (address.isIPv6)
{
    doSomeV6ThingWith(address.bytes.v6);
}
else 
{
    doSomeV4ThingWith(address.bytes.v4);
}

历史上,union也被用来将一种类型的位转换为另一种类型的对象。这是因为,在 union 中,成员都从相同的内存地址开始。如果我这样做:

float f = 3.0;
int i = f;

编译器将插入代码将 float 转换为整数,因此指数将丢失。然而,在

union 
{
    unsigned int i;
    float f;
} x;

x.f = 3.0;
int i = x.i;

i 现在包含表示 float 中的 3.0 的精确位。或者至少你希望如此。 C 标准中没有规定 floatunsigned int 必须具有相同的大小。 C 标准中也没有强制要求 float 的特定表示(嗯,附件 F 说浮点符合 IEC 60559 ,但我不知道这是否算作标准的一部分)。所以上面的代码充其量是不可移植的。

要获取float的指数,可移植的方法是 frexpf() math.h

中定义的函数

how could I manipulate the f2i function to serve this purpose?

让我们假设一个 float 以 32 位的 IEC 60559 格式存储,Wkipedia 认为它与 IEEE 754 相同。 。我们还假设整数以小端格式存储。

union 
{
    uint32_t i;
    float f;
} x;

x.f = someFloat;
uint32_t bits = x.i;

bits 现在包含 float 的位模式。单精度 float 如下所示

SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM
^        ^                     ^
bit 31   bit 22                bit 0

其中S是符号位,E是指数位,M是尾数位。

因此,获得 int32_t 后,您只需要进行一些移位和屏蔽:

uint32_t exponentWithBias = (bits >> 23) & 0xff;

关于c - 在c中获取 float 的指数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46339320/

相关文章:

c++ - 键盘重复计数

java - 在 Java 中有意义地比较两个字符串

css-float - 更改向右浮动的垂直菜单项的宽度

html - CSS 定位和 float

C++ 将 float 组转换为浮点*(指针)

c - 排序堆栈

无法从c中的堆栈结构复制字符串

c - 在 Quake 中使用 CreateEvent()

go - 让 Go 编译器默认使用 int64

visual-studio-2012 - 为什么 TFS 内部版本号在 2012 年停止自动递增?