📄 fixedpoint.java
字号:
package com.j2medev.chapter5;/** * @name FixedPoint * @brief fixed point math operations class * @author sunyuzhe <sunyuzhe@hotmail.com> * @version 1.16 */public final class FixedPoint{ ///////////////////////////////////////////////////////// /// Variables /// ///////////////////////////////////////////////////////// /** Public */ public static final int FIX_SHIFT = 16; public static final int FIX_UNIT = (1<<FIX_SHIFT); public static final int FIX_FRACMASK = (FIX_UNIT-1); public static final int FIX_INTMASK = (~FIX_FRACMASK); /* * angle constants with fixed shift of 16 * PI = 3.1416 * HALFPI = 1.5708 */ public static final int FIXED_PI = 205887; public static final int FIXED_HALFPI = 102943; public static final int FIXED_QUARTERPI = 51471; /** Private */ private static byte[] gP = new byte[21]; private static byte[] gA = new byte[21]; private static StringBuffer gB = new StringBuffer(23); ///////////////////////////////////////////////////////// /// Methods ///////////////////////////////////////////////////////// /** * @brief converts fixed-point back to integer * @param x fixed-point value * @return converted integer value */ public static final int toInt(int x) { return x>>FIX_SHIFT; }/// ~func /** * @brief converts integer value to fixed-point * @param x integer value * @return converted fixed-point value */ public static final int toFix(int x) { return x<<FIX_SHIFT; }/// ~func /** * @brief multiplies fixed-point values x & y each by other * @param x fixed-point value * @param y fixed-point value * @return multiplication value */ public static final int Mul(int x, int y) { return ((int) (((long) x * (long) y) >> FIX_SHIFT)); }/// END FUNC /** * @brief multiplies fixed-point values x & y each by other * @param x fixed-point value * @param y fixed-point value * @return multiplication value in long type */ public static final long lMul(int x, int y) { return ((((long) x * (long) y) >> FIX_SHIFT)); }/// END FUNC /** * @name MulFixedPoint * @brief multiplies fixed-point values x & y each by other * @param x fixed-point value * @param y fixed-point value * @return multiplication value */ public static final long MulFixedPoint(long x, long y) { return (long) x * (long) y; }/// END FUNC /** * @brief calculates fixed-point division x by y * @param x fixed-point divided value * @param y fixed-point divisor value * @return fixed-point calculated division x by y */ public static final int Div(int x, int y) { return (int) (((((long) x) << FIX_SHIFT << FIX_SHIFT) / y) >> FIX_SHIFT); }/// ~func /** * @name Sqrt * @brief returns square root of x * @author Stellars Henson * @param x value to calculate sqrt from * @return FixedPoint sqrt value */ public static final int Sqrt( int x ) { /* prepare environment */ /* Fixedpoint sqrt table size */ long index = FIX_SQRT.length; long dx, dy, darg; long value = 0; long arg_left = 0; long arg_right = 0; long left, right; /* special circumstances */ if( x==0 ) return 0; /* find index, start from highest mask - the youngest 8-th octet */ if( (x & 0xf0000000) != 0 ) index = index - 1*(15) + ((x & 0xf0000000)>>28) - 1; else if( (x & 0x0f000000) != 0 ) index = index - 2*(15) + ((x & 0x0f000000)>>24) - 1; else if( (x & 0x00f00000) != 0 ) index = index - 3*(15) + ((x & 0x00f00000)>>20) - 1; else if( (x & 0x000f0000) != 0 ) index = index - 4*(15) + ((x & 0x000f0000)>>16) - 1; else if( (x & 0x0000f000) != 0 ) index = index - 5*(15) + ((x & 0x0000f000)>>12) - 1; else if( (x & 0x00000f00) != 0 ) index = index - 6*(15) + ((x & 0x00000f00)>>8) - 1; else if( (x & 0x000000f0) != 0 ) index = index - 7*(15) + ((x & 0x000000f0)>>4) - 1; else if( (x & 0x0000000f) != 0 ) index = index - 8*(15) + ((x & 0x0000000f)>>0) - 1; /* linearize sqrt value between neighbours */ arg_left = FIX_SQRT[(int)index][0]; arg_right = FIX_SQRT[(int)index+1][0]; left = FIX_SQRT[(int)index][1]; right = FIX_SQRT[(int)index+1][1]; darg = (arg_right-arg_left); dy = (right-left); dx = (x - arg_left); /* signs */ dx = (dx<0) ? -dx : dx; dy = (dy<0) ? -dy : dy; darg = (darg<0) ? -darg : darg; /* linearization */ value = (long)Div( (int)dy, (int)darg ); value = left + lMul( (int)value, (int)dx ); /* rescale to fixedpoint answer */ value = value>>8; /* while index found, calculate sqrt */ return( (int)value ); }/// END FUNC /** * @name lSqrt * @brief returns square root of x * @author Stellars Henson * @param x value to calculate sqrt from * @return long FixedPoint sqrt value */ public static final long lSqrt( long x ) { /* prepare environment */ /* Fixedpoint sqrt table size */ long index = FIX_SQRT.length; long dx, dy, darg; long value = 0; long arg_left = 0; long arg_right = 0; long left, right; /* special circumstances */ if( x==0 ) return 0; /* find index, start from highest mask - the youngest 8-th octet */ if( (x & 0xf0000000) != 0 ) index = index - 1*(15) + ((x & 0xf0000000)>>28) - 1; else if( (x & 0x0f000000) != 0 ) index = index - 2*(15) + ((x & 0x0f000000)>>24) - 1; else if( (x & 0x00f00000) != 0 ) index = index - 3*(15) + ((x & 0x00f00000)>>20) - 1; else if( (x & 0x000f0000) != 0 ) index = index - 4*(15) + ((x & 0x000f0000)>>16) - 1; else if( (x & 0x0000f000) != 0 ) index = index - 5*(15) + ((x & 0x0000f000)>>12) - 1; else if( (x & 0x00000f00) != 0 ) index = index - 6*(15) + ((x & 0x00000f00)>>8) - 1; else if( (x & 0x000000f0) != 0 ) index = index - 7*(15) + ((x & 0x000000f0)>>4) - 1; else if( (x & 0x0000000f) != 0 ) index = index - 8*(15) + ((x & 0x0000000f)>>0) - 1; /* linearize sqrt value between neighbours */ arg_left = FIX_SQRT[(int)index][0]; arg_right = FIX_SQRT[(int)index+1][0]; left = FIX_SQRT[(int)index][1]; right = FIX_SQRT[(int)index+1][1]; darg = (arg_right-arg_left); dy = (right-left); dx = (x - arg_left); /* signs */ dx = (dx<0) ? -dx : dx; dy = (dy<0) ? -dy : dy; darg = (darg<0) ? -darg : darg; /* linearization */ value = (long)Div( (int)dy, (int)darg ); value = left + lMul( (int)value, (int)dx ); /* rescale to fixedpoint answer */ value = value>>8; /* while index found, calculate sqrt */ return( value ); }/// END FUNC /** * @brief rounds given fixed-point number to nearest integer value * @param n fixed-point value * @return nearest integer value */ public static final int round(int n) { if (n > 0) { if ((n & (FIX_UNIT>>1)) != 0) return (((n+FIX_UNIT)>>FIX_SHIFT)<<FIX_SHIFT); else return (((n)>>FIX_SHIFT)<<FIX_SHIFT); }// ~if else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -