在Java中将浮点转换为32位定点

时间:2010-08-04 04:57:43

标签: java algorithm math compression

我必须在Java中将浮点数转换为32位固定点。

无法理解什么是32位定点?

任何身体都可以帮助算法吗?

4 个答案:

答案 0 :(得分:20)

定点数是使用整数部分的类型的特定位数的实数的表示,以及小数部分的类型的其余位。表示每个部分的位数是固定的(因此名称,定点)。整数类型通常用于存储定点值。

定点数通常用于没有浮点支持的系统,或者需要比浮点数更快的系统。可以使用CPU的整数指令执行定点计算。

32位定点数将存储在32位类型中,例如int

通常,(在这种情况下为无符号)整数类型中的每个位将表示一个整数值2 ^ n,如下所示:

 1    0    1    1    0    0    1    0       = 2^7 + 2^5 + 2^4 + 2^1 = 178
2^7  2^6  2^5  2^4  2^3  2^2  2^1  2^0

但如果该类型用于存储定点值,则这些位的解释略有不同:

 1    0    1    1    0    0    1    0       = 2^3 + 2^1 + 2^0 + 2^-3 = 11.125
2^3  2^2  2^1  2^0  2^-1 2^-2 2^-3 2^-4

上例中的定点数称为4.4定点数,因为整数部分有4位,数字的小数部分有4位。在32位类型中,定点值通常为16.16格式,但也可以是24.8,28.4或任何其他组合。

从浮点值转换为定点值包括以下步骤:

  1. 将浮点数乘以2 ^(类型的小数位数),例如。 2 ^ 8 for 24.8
  2. 如果需要,将结果舍入(只需加0.5),然后将其置换(或转换为整数类型),留下整数值。
  3. 将此值指定为定点类型。
  4. 显然,你可以在数字的小数部分失去一些精确度。如果小数部分的精度很重要,定点格式的选择可以反映这一点 - 例如。使用16.16或8.24而不是24.8。

    如果需要对定点数进行签名,也可以采用相同的方式处理负值。

    如果我的Java更强大,我会尝试一些代码,但我通常用C编写这样的东西,所以我不会尝试Java版本。此外,堆栈器的版本对我来说看起来不错,但有一个小例外,它不提供舍入的可能性。他甚至会告诉你如何进行乘法运算(转变非常重要!)

答案 1 :(得分:4)

转换为固定点的一个非常简单的示例,它显示了如何转换和乘以PI by2。结果将转换回double,以证明在使用整数计算时尾数没有丢失。

您可以使用sin()和cos()查找表等轻松扩展它。 如果您打算使用固定点来查找java定点库,我会建议。

public class Fix {

    public static final int FIXED_POINT = 16;
    public static final int ONE = 1 << FIXED_POINT;

    public static int mul(int a, int b) {
        return (int) ((long) a * (long) b >> FIXED_POINT);
    }

    public static int toFix( double val ) {
        return (int) (val * ONE);
    }

    public static int intVal( int fix ) {
        return fix >> FIXED_POINT;
    }

    public static double doubleVal( int fix ) {
        return ((double) fix) / ONE;
    }

    public static void main(String[] args) {
        int f1 = toFix( Math.PI );
        int f2 = toFix( 2 );

        int result = mul( f1, f2 );
        System.out.println( "f1:" + f1 + "," + intVal( f1 ) );
        System.out.println( "f2:" + f2 + "," + intVal( f2 ) );
        System.out.println( "r:" + result +"," + intVal( result));
        System.out.println( "double: " + doubleVal( result ));

    }
}

输出

f1:205887,3
f2:131072,2
r:411774,6
double: 6.283172607421875

答案 2 :(得分:2)

定点类型是在小数点后具有固定数量的十进制/二进制位数的类型。或者更一般地,一种类型可以存储一些正整数N的1 / N的倍数。

在内部,定点数值存储为值乘以比例因子。例如,存储比例因子为100的123.45,就像它是整数12345一样。

要将定点数的内部值转换为浮点数,只需除以比例因子即可。要转换另一种方式,请乘以缩放系数并舍入为最接近的整数。

答案 3 :(得分:1)

32位定点的定义可能会有所不同。固定点的一般思想是,您在之前有一些固定的位数,在小数点(或二进制点)之后有另一个固定的位数。对于一个32位的,最常见的分割可能是偶数(前16个,后16个),但根据目的不能保证。

就转换而言,再次对某些变化开放 - 例如,如果输入数字超出目标范围,您可能想要做任何数量的不同事情(例如,在某些情况下,环绕可能有意义,但在其他人可能更喜欢饱和度。)