我正在写一个函数,会得到一个浮点数的指数(IEEE 754标准),但由于某些原因,当我使用右移位运算符的数量则返回0获取指数从浮点用C
下面是函数
int get_exp (int x)
{
return (((x >> 21) & 255) -127);
}
我传递7.23所以输出应该是2,由于某种原因(X >> 21)部分返回0时,它实际上应该返回129。 255是我使用掩模和(&)与浮点数的指数部分。
我正在写一个函数,会得到一个浮点数的指数(IEEE 754标准),但由于某些原因,当我使用右移位运算符的数量则返回0获取指数从浮点用C
下面是函数
int get_exp (int x)
{
return (((x >> 21) & 255) -127);
}
我传递7.23所以输出应该是2,由于某种原因(X >> 21)部分返回0时,它实际上应该返回129。 255是我使用掩模和(&)与浮点数的指数部分。
我猜你正在做某种铸造hocus-pocus来通过浮点数为int
s?我将使用中定义的float frexpf (float x, int* exp);
。
#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
,或者如果你切换字节顺序。
我必须这样做,而不使用任何已定义的功能 –
@Yimin Rong有没有办法做到这一点没有frexp? –
@KareemYoussef - 添加了代码,但没有保证! –
参数列表显示
int x
,你传递一个浮点数。试着用
float x
一个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
可以在不使用float数据类型的情况下完成吗? –
@KareemYoussef它不能,否则有问题的数字将不会采用IEE 754浮点格式。除非你从一个字节数组手动构造它,也就是说。 – dbush
性能是否应不是问题,只需重复:
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
主要问题是int
,而不是float
的传球和使用21比23。@dbush
IEEE 754标准(binary32)有许多不同的情况:Inifinty,NaN,包括零的子正常。所以需要额外的代码来应对它们。
假设正确尾数:中
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;
}
邮编例如“我通过它7.23” – chux
为什么在上面的代码右移通过'21',而不是由'23'位? – njuffa