将浮点数转换为 Java 中的 32 位定点数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3402702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
converting floating point to 32-bit fixed point in Java
提问by Abhijith V R
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 ?
任何机构都可以帮助算法吗?
回答by Jerry Coffin
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.
32 位定点的定义可能会有所不同。定点的一般思想是您在小数点(或二进制小数点)之前有一些固定数量的位,而在小数点之后有另一个固定数量的位。对于 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 (e.g., in some cases wraparound could make sense, but in others saturation might be preferred).
就转换而言,它再次对某些变化开放——例如,如果输入数字超出目标范围,您可能想要做任何数量的不同事情(例如,在某些情况下,环绕可能有意义,但在其他情况下可能更喜欢饱和)。
回答by dan04
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.
要将定点数的内部值转换为浮点数,只需除以比例因子即可。要以另一种方式转换,请乘以比例因子并四舍五入到最接近的整数。
回答by stacker
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.
一个非常简单的转换为定点的例子,它展示了如何转换和乘以 PI by2。结果被转换回 double 以证明尾数在整数计算过程中没有丢失。
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
回答by MatthewD
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 位定点数将存储在 32 位类型中,例如int
.
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. 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.
上例中的定点数称为 4.4 定点数,因为整数部分有 4 位,小数部分有 4 位。在 32 位类型中,定点值通常采用 16.16 格式,但也可以是 24.8、28.4 或任何其他组合。
Converting from a floating-point value to a fixed-point value involves the following steps:
从浮点值转换为定点值涉及以下步骤:
- Multiply the float by 2^(number of fractional bits for the type), eg. 2^8 for 24.8
- Round the result (just add 0.5) if necessary, and floor it (or cast to an integer type) leaving an integer value.
- Assign this value into the fixed-point type.
- 将浮点数乘以 2^(类型的小数位数),例如。2^8 为 24.8
- 如有必要,将结果四舍五入(只需添加 0.5),并将其取整(或强制转换为整数类型),留下一个整数值。
- 将此值分配给定点类型。
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. 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!)
如果我的 Java 更强大,我会尝试一些代码,但我通常用 C 编写这些东西,所以我不会尝试 Java 版本。此外,stacker的版本对我来说看起来不错,唯一的例外是它不提供四舍五入的可能性。他甚至向您展示了如何执行乘法(移位很重要!)