功能转换为浮动INT(整数巨大) [英] function to convert float to int (huge integers)

查看:405
本文介绍了功能转换为浮动INT(整数巨大)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一所大学的问题。只是为了确保:-)我们需要实现(浮点)X

This is a university question. Just to make sure :-) We need to implement (float)x

我有以下的code,必须x转换为存储在一个无符号整数,它的浮点二进制重新presentation整数。

I have the following code which must convert integer x to its floating point binary representation stored in an unsigned integer.

unsigned float_i2f(int x) {
  if (!x) return x;

  /* get sign of x */
  int sign = (x>>31) & 0x1;

  /* absolute value of x */
  int a = sign ? ~x + 1 : x;

  /* calculate exponent */
  int e = 0;
  int t = a;
  while(t != 1) {
    /* divide by two until t is 0*/
    t >>= 1;
    e++;
  };

  /* calculate mantissa */
  int m = a << (32 - e);
  /* logical right shift */
  m = (m >> 9) & ~(((0x1 << 31) >> 9 << 1));

  /* add bias for 32bit float */
  e += 127;

  int res = sign << 31;
  res |= (e << 23);
  res |= m;

  /* lots of printf */

  return res;
}

一个问题我现在遇到的是,当我的整数是太大了,然后我code失败。我有这个控制程序实现的:

One problem I encounter now is that when my integers are too big then my code fails. I have this control procedure implemented:

float f = (float)x;
unsigned int r;
memcpy(&r, &f, sizeof(unsigned int));

这当然总是产生正确的输出。

This of course always produces the correct output.

现在,当我做了一些测试运行,这是我的输出(目标是什么它需要,结果我得到了什么)

Now when I do some test runs, this are my outputs (GOAL is what It needs to be, result is what I got)

:!make && ./btest -f float_i2f -1 0x80004999                                                                  
make: Nothing to be done for `all'.
Score   Rating  Errors  Function
x: [-2147464807]        10000000000000000100100110011001
sign: 1
expone: 01001110100000000000000000000000
mantis: 00000000011111111111111101101100
result: 11001110111111111111111101101100
GOAL:   11001110111111111111111101101101

因此​​,在这种情况下,加1作为LSB的

So in this case, a 1 is added as the LSB.

下一页案例:

:!make && ./btest -f float_i2f -1 0x80000001
make: Nothing to be done for `all'.
Score   Rating  Errors  Function
x: [-2147483647]        10000000000000000000000000000001
sign: 1
expone: 01001110100000000000000000000000
mantis: 00000000011111111111111111111111
result: 11001110111111111111111111111111
GOAL:   11001111000000000000000000000000

下面加1的指数,而尾数是它的补码。

Here 1 is added to the exponent while the mantissa is the complement of it.

我试过小时查找IP在互联网上加上我的书等,但我无法找到这个问题的任何引用。我猜它是与事实尾数只有23位。但是我必须如何处理它呢?

I tried hours to look ip up on the internet plus in my books etc but I can't find any references to this problem. I guess It has something to do with the fact that the mantissa is only 23 bits. But how do I have to handle it then?

编辑:这部分是已过时的感谢下面的评论。 int类型l必须是无符号负于

THIS PART IS OBSOLETE THANKS TO THE COMMENTS BELOW. int l must be unsigned l.

int x = 2147483647; 
float f = (float)x;

int l = f;
printf("l: %d\n", l);

那么L变成-2147483648。

then l becomes -2147483648.

怎么能这样呢?所以C是做铸件错了?

How can this happen? So C is doing the casting wrong?

希望有人能帮助我在这里!
谢谢
马库斯

Hope someone can help me here! Thx Markus

编辑2:

我的更新code现在是这样的:

My updated code is now this:

unsigned float_i2f(int x) {
  if (x == 0) return 0;
  /* get sign of x */
  int sign = (x>>31) & 0x1;

  /* absolute value of x */
  int a = sign ? ~x + 1 : x;

  /* calculate exponent */
  int e = 158;
  int t = a;
  while (!(t >> 31) & 0x1) {
    t <<= 1;
    e--;
  };

  /* calculate mantissa */
  int m = (t >> 8) & ~(((0x1 << 31) >> 8 << 1));
  m &= 0x7fffff;

  int res = sign << 31;
  res |= (e << 23);
  res |= m;

  return res;
}

我也想通了,在code工作在范围-2 ^ 24,2 ^ 24的所有整数。高于/低于有时工作,但大多都没有。

I also figured out that the code works for all integers in the range -2^24, 2^24. Everything above/below sometimes works but mostly doesn't.

东西丢失,但我真的不知道。谁能帮我?

Something is missing, but I really have no idea what. Can anyone help me?

推荐答案

打印的答案是绝对正确的,因为它是完全依靠数字是铸铁的基本重新presentation。但是,如果我们理解数字的二进制重新presentation,你不会得到这个结果感到惊讶。

The answer printed is absolutely correct as it's totally dependent on the underlying representation of numbers being cast. However, If we understand the binary representation of the number, you won't get surprised with this result.

要了解的隐式转换与赋值运算符(参见C99标准6.5.16)有关。 C99标准接着说:

To understand an implicit conversion is associated with the assignment operator (ref C99 Standard 6.5.16). The C99 Standard goes on to say:

6.3.1.4实型浮点和整数
  当真实浮动型的有限值转换为比_Bool以外的整数类型,小数部分被丢弃(即,该值向零截断)。如果组成部分的价值不能被整型psented重新$ P $,其行为是不确定的。

6.3.1.4 Real floating and integer When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.

您刚才的例子说明,由于分配目标类型的范围外的值未定义行为。试图为负值分配给无符号的类型,而不是从浮点转换为整数。

Your earlier example illustrates undefined behavior due to assigning a value outside the range of the destination type. Trying to assign a negative value to an unsigned type, not from converting floating point to integer.

断言应该prevent发生任何不确定的行为。

The asserts in the following snippet ought to prevent any undefined behavior from occurring.

#include <limits.h>
#include <math.h>
unsigned int convertFloatingPoint(double v) {
   double d;
   assert(isfinite(v));
   d = trunc(v);
   assert((d>=0.0) && (d<=(double)UINT_MAX));
   return (unsigned int)d;
}

另一种方式做同样的事情,建立一个包含32位的整数和浮点工会。 INT和浮动现在看着相同的内存位只是方式不同;

Another way for doing the same thing, Create a union containing a 32-bit integer and a float. The int and float are now just different ways of looking at the same bit of memory;

union {
    int    myInt;
    float myFloat;
} my_union;

my_union.myInt = 0x BFFFF2E5;

printf("float is &#37;f\n", my_union.myFloat);

float is -1.999600

您告诉编译器把你拥有的数量(大整数),使之成为一个浮动,不跨preT为float数。要做到这一点,你需要告诉编译器来读取以不同的形式从该地址的数量,因此这样的:

You are telling the compiler to take the number you have (large integer) and make it into a float, not to interpret the number AS float. To do that, you need to tell the compiler to read the number from that address in a different form, so this:

myFloat = *(float *)&myInt ;

这意味着,如果我们把它拆开,从右侧开始:

That means, if we take it apart, starting from the right:


  • &安培;敏 - 在内存中保存您的整数位置

  • (浮点*) - 真的,我希望编译以此为指针浮动,没有任何编译器认为它可能是

  • 。* - 从什么是正确的地址读

  • myFloat = - 这个变量来无论是在右边

  • &myInt - the location in memory that holds your integer.
  • (float *) - really, I want the compiler use this as a pointer to float, not whatever the compiler thinks it may be.
  • * - read from the address of whatever is to the right.
  • myFloat = - set this variable to whatever is to the right.

所以,你告诉编译器:在(敏)的位置,有一个浮点数,现在把花车进入myFloat。

So, you are telling the compiler: In the location of (myInt), there is a floating point number, now put that float into myFloat.

这篇关于功能转换为浮动INT(整数巨大)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆