0

我正在尝试使用 C 中的位运算来舍入浮点数。我首先将浮点数转换为无符号整数。我认为我的策略应该是获取指数,然后将位归零,但我不确定如何编码。这是我到目前为止所拥有的:

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. 
4

2 回答 2

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;
}
于 2013-02-13T03:11:14.800 回答
0

float roundDown(float f);应该是float roundDown(float f) {

unsigned int notRounded = *(unsigned int *)&f;与现代编译器优化不兼容。查找“<a href="https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule">严格别名”。

这是一个向下取整到 2 次方的工作函数:

#include <stdio.h>
#include <assert.h>
#include <string.h>

float roundDown(float f) {
  unsigned int notRounded;
  assert(sizeof(int) == sizeof(float));
  memcpy(&notRounded, &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
于 2013-02-09T23:42:07.107 回答