我正在尝试使用C中的位操作向下舍入浮点数。 我首先将float转换为unsigned int。 我认为我的策略应该是获取指数,然后在那之后将位清零,但我不知道如何编码。这就是我到目前为止所做的:
float roundDown(float f);
unsigned int notRounded = *(unsigned int *)&f;
unsigned int copy = notRounded;
int exponent = (copy >> 23) & 0xff;
int fractional = 127 + 23 - exponent;
if(fractional > 0){
//not sure how to zero out the bits.
//Also don't know how to deal with the signed part.
答案 0 :(得分:1)
由于它只是为了好玩,而且我不确定这些约束是什么,这里有一个适用于负数的变体:
float myRoundDown_1 (float v) { //only works right for positive numbers
return ((v-0.5f)+(1<<23)) - (1<<23);
}
float myRoundDown_2 (float v) { //works for all numbers
static union {
unsigned long i;
float f;
} myfloat;
unsigned long n;
myfloat.f = v;
n = myfloat.i & 0x80000000;
myfloat.i &= 0x7fffffff;
myfloat.f = myRoundDown_1(myfloat.f+(n>>31));
myfloat.i |= n;
return myfloat.f;
}
答案 1 :(得分:0)
float roundDown(float f);
应为float roundDown(float f) {
。
unsigned int notRounded = *(unsigned int *)&f;
与现代编译器优化不兼容。查看“strict aliasing”。
这是一个向下舍入到2的幂的工作函数:
#include <stdio.h>
#include <assert.h>
#include <string.h>
float roundDown(float f) {
unsigned int notRounded;
assert(sizeof(int) == sizeof(float));
memcpy(¬Rounded, &f, sizeof(int));
// zero out the significand (mantissa):
unsigned int rounded = notRounded & 0xFF800000;
float r;
memcpy(&r, &rounded, sizeof(int));
return r;
}
int main()
{
printf("%f %f\n", 1.33, roundDown(1.33));
printf("%f %f\n", 3.0, roundDown(3.0));
}
这应该产生:
1.330000 1.000000
3.000000 2.000000