我正在编写一个函数,它将获得浮点数(IEEE 754标准)的指数但由于某种原因,当我在数字上使用右移位运算符时,它返回0
这是函数
int get_exp (int x)
{
return ( ((x >> 21) & 255) -127 );
}
我正在传递它7.23所以输出应该是2,由于某种原因,(x>>> 21)部分返回0时它应该实际返回129. 255是我正在使用的掩码和(&),浮点数的指数部分。
答案 0 :(得分:7)
我猜你正在做某种投射hocus-pocus以将浮点传递为int
s?我会使用float frexpf (float x, int* exp);
中定义的<math.h>
。
#include <math.h>
int get_exp(float x)
{
int exp;
frexpf(x, &exp);
return exp;
}
无论浮点类型的大小如何,它都能保证正常工作。
如果您想自己滚动,可以调整此代码。
#define EXPONENT_BIAS (-127)
int get_exp(float f)
{
int i;
union {
// Set here, then use s or c to extract
float f;
// This may or may not work for you
struct {
unsigned int sign: 1;
unsigned int exponent: 8;
unsigned int mantissa: 23;
} s;
// For debugging purposes
unsigned char c[sizeof(float)];
} u;
// Assign, you might need to reverse the bytes!
u.f = f;
// You'll probably need this to figure out the field widths
for (i = 0; i < sizeof(float); i++)
fprintf(stderr, "%02x%s", u.c[i], (i + 1 < sizeof(float))? " ": "\n");
// Just return the exponent
return (int)u.s.exponent + EXPONENT_BIAS;
}
如果您sizeof(float) != 4
或切换字符串,这会让您感到痛苦。
答案 1 :(得分:2)
假设float
为32位并且布局为as specified here,您有三个问题:
float
。uint32_t
指向float
的地址,以便它看到相同的字节,然后针对取消引用的指针执行操作。#include <stdio.h>
#include <stdint.h>
int get_exp (float x)
{
uint32_t *i = (uint32_t *)&x;
return ( ((*i >> 23) & 255) -127 );
}
int main()
{
printf("exp=%d\n",get_exp(7.23));
}
结果:
exp=2
答案 2 :(得分:0)
如果性能不成问题,只需迭代:
int expof(float f) {
int expo = 0;
if (f < 0.0) f = -f;
while (f < 0.5f) {
f *= 2.0f;
expo--;
}
while (f >= 1.0f) {
f *= 0.5f;
expo++;
}
return expo;
}
除了指数适合float
之外,不依赖于任何特定的int
实现。它不使用外部函数作为注释here。
与int expo; frexpf(f, &expo); return expo
答案 3 :(得分:0)
主要问题是int
而不是float
并使用21 vs 23. @dbush
IEEE 754标准(binary32)有许多极端情况:Inifinty,NaN,sub-normal包括零。因此需要额外的代码来应对它们。
假设有适当的结尾:
int get_exp(float x) {
assert(sizeof x == sizeof(uint32_t));
union {
float x;
uint32_t u32;
} u = { x };
#define EXPOSHIFT 23
#define EXPOMASK 255
#define EXPOBIAS 127
if (x == 0.0) return 0;
int expo = (int) (u.u32 >> EXPOSHIFT) & EXPOMASK;
if (expo == EXPOMASK) return INT_MAX; // x is infinity or NaN
if (expo == 0) return get_exp(x * (1L << EXPOSHIFT)) - EXPOSHIFT;
return expo - EXPOBIAS;
}
答案 4 :(得分:-1)
参数列表显示
int x
并传递浮点数。尝试用
代替float x