Java中浮点数转换为32位定点数

发布于 2024-09-12 22:56:16 字数 77 浏览 2 评论 0原文

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

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

任何人都可以帮助算法吗?

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

╰ゝ天使的微笑 2024-09-19 22:56:16

定点数是使用某种类型的特定位数作为整数部分、使用该类型的其余位作为小数部分的实数表示形式。表示每个部分的位数是固定的(因此得名定点)。整数类型通常用于存储定点值。

定点数通常用在不支持浮点的系统中,或者需要比浮点所能提供的更快的速度。可以使用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. 将此值分配给定点类型。

显然,您可能会失去数字小数部分的一些精度。如果小数部分的精度很重要,那么定点格式的选择可以反映这一点 - 例如。使用 16.16 或 8.24 而不是 24.8。

如果您的定点数需要签名,也可以以相同的方式处理负值。

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

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!)

べ映画 2024-09-19 22:56:16

转换为定点的一个非常简单的示例,它展示了如何转换 PI 并将其乘以 2。结果被转换回双精度,以证明在整数计算过程中尾数没有丢失。

您可以使用 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

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
寂寞花火° 2024-09-19 22:56:16

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

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

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

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.

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.

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.

迷你仙 2024-09-19 22:56:16

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

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

The definition of 32-bit fixed point could vary. 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.

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 (e.g., in some cases wraparound could make sense, but in others saturation might be preferred).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文