简体   繁体   English

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

[英]converting floating point to 32-bit fixed point in Java

I have to convert a floating point to 32-bit fixed point in Java . 我必须在Java中将浮点转换为32位固定点。

Not able to understand what is a 32-bit fixed point ? 无法理解什么是32位定点?

Can any body help with algorithm ? 任何机构都可以帮助算法吗?

A fixed-point number is a representation of a real number using a certain number of bits of a type for the integer part, and the remaining bits of the type for the fractional part. 定点数是实数的表示,其中整数部分使用一定类型的位数,而小数部分使用类型的其余位数。 The number of bits representing each part is fixed (hence the name, fixed-point). 表示每个部分的位数是固定的(因此,名称为定点)。 An integer type is usually used to store fixed-point values. 通常使用整数类型存储定点值。

Fixed-point numbers are usually used in systems which don't have floating point support, or need more speed than floating point can provide. 定点数通常用于没有浮点支持或需要比浮点提供更多速度的系统中。 Fixed-point calculations can be performed using the CPU's integer instructions. 定点计算可以使用CPU的整数指令执行。

A 32-bit fixed-point number would be stored in an 32-bit type such as int . 32位定点数将以int类的32位类型存储。

Normally each bit in an (unsigned in this case) integer type would represent an integer value 2^n as follows: 通常,(在这种情况下为无符号)整数类型中的每个位都将表示一个整数值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

But if the type is used to store a fixed-point value, the bits are interpreted slightly differently: 但是,如果使用该类型存储定点值,则位的解释会稍有不同:

 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

The fixed point number in the example above is called a 4.4 fixed-point number, since there are 4 bits in the integer part and 4 bits in the fractional part of the number. 上面示例中的定点数称为4.4定点数,因为该数的整数部分为4位,小数部分为4位。 In a 32 bit type the fixed-point value would typically be in 16.16 format, but also could be 24.8, 28.4 or any other combination. 在32位类型中,定点值通常为16.16格式,但也可以为24.8、28.4或任何其他组合。

Converting from a floating-point value to a fixed-point value involves the following steps: 从浮点值转换为定点值涉及以下步骤:

  1. Multiply the float by 2^(number of fractional bits for the type), eg. 浮点数乘以2 ^(该类型的小数位数),例如。 2^8 for 24.8 2 ^ 8为24.8
  2. Round the result (just add 0.5) if necessary, and floor it (or cast to an integer type) leaving an integer value. 如有必要,对结果进行四舍五入(只需添加0.5),并将其取整(或强制转换为整数类型),剩下一个整数值。
  3. Assign this value into the fixed-point type. 将此值分配给定点类型。

Obviously you can lose some precision in the fractional part of the number. 显然,您可能会损失数字的小数部分的精度。 If the precision of the fractional part is important, the choice of fixed-point format can reflect this - eg. 如果小数部分的精度很重要,那么定点格式的选择可以反映出这一点-例如。 use 16.16 or 8.24 instead of 24.8. 使用16.16或8.24代替24.8。

Negative values can also be handled in the same way if your fixed-point number needs to be signed. 如果需要对定点数字进行签名,则负值也可以用相同的方式处理。

If my Java were stronger I'd attempt some code, but I usually write such things in C, so I won't attempt a Java version. 如果我的Java更强大,我会尝试一些代码,但是我通常用C编写这样的东西,所以我不会尝试Java版本。 Besides, stacker 's version looks good to me, with the minor exception that it doesn't offer the possibility of rounding. 此外, stacker的版本对我来说看起来不错,但有一点例外,它没有舍入的可能性。 He even shows you how to perform a multiplication (the shift is important!) 他甚至向您展示了如何进行乘法(移位很重要!)

A very simple example for converting to fixed point, it shows how to convert and multiplies PI by2. 一个非常简单的转换为定点的示例,它显示了如何将PI乘以2。 The resulting is converted back to double to demonstrate that the mantissa wasn't lost during calculation with integers. 将结果转换回两倍,以证明在使用整数进行计算时尾数未丢失。

You could expand that easily with sin() and cos() lookup tables etc. I would recommend if you plan to use fixed point to look for a java fixed point library. 您可以使用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 ));

    }
}

OUTPUT 输出值

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

A fixed-point type is one that has a fixed number of decimal/binary places after the radix point. 定点类型是在小数点后具有固定数量的小数/二进制位的类型。 Or more generally, a type that can store multiples of 1/N for some positive integer N. 或更一般而言,对于某些正整数N,可以存储1 / N的倍数的类型。

Internally, fixed-point numbers are stored as the value multiplied by the scaling factor. 在内部,定点数存储为值乘以比例因子。 For example, 123.45 with a scaling factor of 100 is stored as if it were the integer 12345. 例如,存储比例因子为100的123.45,就好像它是整数12345。

To convert the internal value of a fixed-point number to floating point, simply divide by the scaling factor. 要将定点数的内部值转换为浮点数,只需除以比例因子即可。 To convert the other way, multiply by the scaling factor and round to the nearest integer. 要进行另一种转换,请乘以比例因子并四舍五入为最接近的整数。

The definition of 32-bit fixed point could vary. 32位定点的定义可能会有所不同。 The general idea of fixed point is that you have some fixed number of bits before and another fixed number of bits after the decimal point (or binary point). 定点的一般想法是,在小数点(或二进制点)之前有一些固定位数,在小数点之后有另一固定位数。 For a 32-bit one, the most common split is probably even (16 before, 16 after), but depending on the purpose there's no guarantee of that. 对于32位,最常见的分割可能是偶数(16位在前,16位在后),但根据目的,无法保证。

As far as the conversion goes, again it's open to some variation -- for example, if the input number is outside the range of the target, you might want to do any number of different things (eg, in some cases wraparound could make sense, but in others saturation might be preferred). 就转换而言,它还是有一些变化的余地-例如,如果输入数字超出目标范围,则您可能想要做许多不同的事情(例如,在某些情况下,回绕可能很有意义,但在其他情况下,饱和度可能更可取)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM