Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

converting floating point to 32-bit fixed point in Java

I have to convert a floating point to 32-bit fixed point in Java .

Not able to understand what is a 32-bit fixed point ?

Can any body help with algorithm ?

like image 457
Abhijith V R Avatar asked Aug 04 '10 04:08

Abhijith V R


People also ask

How do you convert a floating point to a fixed-point?

To convert from floating-point to fixed-point, we follow this algorithm: Calculate x = floating_input * 2^(fractional_bits) Round x to the nearest whole number (e.g. round(x) ) Store the rounded x in an integer container.

How do you convert a decimal to a fixed binary point?

The value on the left of the decimal point is divided by 2 to get the remainder as the binary digits right to left from the binary decimal point. The value on the right of the decimal point is multiplied by 2 to get the whole number as the binary digits from left to right from the binary decimal point.

Can float be converted to long in Java?

The java. lang. Float. longValue() method returns value of this Float as a long (by casting to type long).


2 Answers

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.

A 32-bit fixed-point number would be stored in an 32-bit type such as int.

Normally each bit in an (unsigned in this case) integer type would represent an integer value 2^n as follows:

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

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^8 for 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.
  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.

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. Besides, stacker's version looks good to me, with the minor exception that it doesn't offer the possibility of rounding. He even shows you how to perform a multiplication (the shift is important!)

like image 148
MatthewD Avatar answered Oct 05 '22 00:10

MatthewD


A very simple example for converting to fixed point, it shows how to convert and multiplies PI by2. 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.

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
like image 40
stacker Avatar answered Oct 05 '22 01:10

stacker