Java中浮点到32位定点的转换

Java中浮点到32位定点的转换,java,algorithm,math,compression,Java,Algorithm,Math,Compression,我必须在Java中将浮点转换为32位定点 无法理解什么是32位定点 任何人都能对算法有所帮助吗?32位固定点的定义可能会有所不同。固定点的一般概念是,在小数点(或二进制点)之前有一些固定数量的位,在小数点之后有另一个固定数量的位。对于32位,最常见的拆分可能是偶数(前16位,后16位),但根据用途,无法保证这一点 就转换而言,它也会有一些变化——例如,如果输入数字超出目标范围,您可能需要做许多不同的事情(例如,在某些情况下,环绕可能有意义,但在其他情况下,饱和可能是首选).定点类型是在小数点后有

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

无法理解什么是32位定点


任何人都能对算法有所帮助吗?

32位固定点的定义可能会有所不同。固定点的一般概念是,在小数点(或二进制点)之前有一些固定数量的位,在小数点之后有另一个固定数量的位。对于32位,最常见的拆分可能是偶数(前16位,后16位),但根据用途,无法保证这一点


就转换而言,它也会有一些变化——例如,如果输入数字超出目标范围,您可能需要做许多不同的事情(例如,在某些情况下,环绕可能有意义,但在其他情况下,饱和可能是首选).

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

在内部,定点数字存储为值乘以比例因子。例如,比例因子为100的123.45被存储为整数12345


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

一个转换为定点的非常简单的示例,它演示了如何将PI转换并乘以2。结果被转换回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 ));

    }
}

定点数是实数的表示,整数部分使用某一类型的特定位数,小数部分使用该类型的剩余位数。表示每个部分的位数是固定的(因此命名为定点)。整数类型通常用于存储定点值

固定点号通常用于不支持浮点的系统,或者需要比浮点更快的速度。可以使用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或任何其他组合

从浮点值转换为定点值涉及以下步骤:

  • 将浮点数乘以2^(类型的小数位数),例如2^8表示24.8
  • 如有必要,对结果进行四舍五入(只需添加0.5),并将其降低(或转换为整数类型),留下一个整数值
  • 将此值指定给定点类型
  • 很明显,数字的小数部分可能会失去一些精度。如果分数部分的精度很重要,则定点格式的选择可以反映这一点-例如,使用16.16或8.24而不是24.8

    如果您的固定点号需要签名,也可以用同样的方法处理负值


    如果我的Java更强大,我会尝试一些代码,但我通常用C编写这样的东西,所以我不会尝试Java版本。除此之外,stacker的版本对我来说很好,除了一个小的例外,它不提供舍入的可能性。他甚至向您展示了如何执行乘法运算(这种转换很重要!)

    Java不能进行类型转换吗O+1表示乘法方法。但有两个改进建议:将
    double
    转换为定点时提供舍入;然后重写
    toString()
    ,这样就可以很容易地打印出对定点值的正确解释(然后可以在测试中使用)。我很好奇:
    fix>>fixed\u point
    fix/ONE
    的操作完全相同吗?如果是这样的话,为什么要进行除法(我一直认为这样会比较慢)?另外,你能用乘法运算中的定点解释一下吗?我看到一些消息来源说,如果每个数字有
    m
    十进制位,那么移位必须是
    2m
    (所以
    2*定点
    ):都是正确的,如果你能提供一个解决方案,这样你的答案就可以被接受,那就更好了。幸运的是,我有它,我将把它放在这里:int number=Float.floatToRawIntBits(floatNumber);我也在学习这个固定点的东西。。在你的例子中,10.125*10^4=178吗?它等于162。谢谢大眼人!是-在4.4定点示例中,我的值是错误的。现在修好了。顺便说一句,你的评论中的值应该是2^4,而不是10^4:-)
     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