当前页面: 开发资料首页 → J2ME 专题 → 关于j2me中浮点问题的解决方案[转贴]
关于j2me中浮点问题的解决方案[转贴]
摘要: 关于j2me中浮点问题的解决方案[转贴]
(方案一)
j2me不支持浮点数计算,自己写一个浮点处理类,是再好不过的解决方法了,下面这个类可以解决浮点计算问题,希望对大家有帮助。
package mocoreJ;
import java.lang.Math;
public class CFloat
{
static final CFloat ERROR = new CFloat( 0xfffffffffffe93c6L );
static final int ITNUM = 5;
static final CFloat SQRT3 = new CFloat( 0x1934645eb11L, -12L );
public static final CFloat PI;
public static final CFloat ZERO = new CFloat();
public static final CFloat ONE = new CFloat( 1L );
public static final CFloat PIdiv2;
public static final CFloat PIdiv4;
public static final CFloat PIdiv6;
public static final CFloat PIdiv12;
public static final CFloat PImul2;
public static final CFloat PImul4;
public long m_Val;
public long m_E;
public CFloat()
{
m_Val = m_E = 0L;
}
public CFloat( long value )
{
m_Val = value;
m_E = 0L;
}
public CFloat( long value, long e )
{
m_Val = value;
if( m_Val == ( long )0 )
{
m_E = 0L;
}
else
{
m_E = e;
}
}
public CFloat( CFloat value )
{
m_Val = value.m_Val;
if( m_Val == ( long )0 )
{
m_E = 0L;
}
else
{
m_E = value.m_E;
}
}
public CFloat Abs()
{
return new CFloat( Math.abs( m_Val ), m_E );
}
public long toLong()
{
long tmpE = m_E;
long tmpVal = m_Val;
while( tmpE != ( long )0 )
{
if( tmpE < ( long )0 )
{
tmpVal /= 10;
tmpE++;
}
else
{
tmpVal *= 10;
tmpE--;
}
}
return( long )( int )tmpVal;
}
public int toInt()
{
long tmpE = m_E;
long tmpVal = m_Val;
while( tmpE != ( long )0 )
{
if( tmpE < ( long )0 )
{
tmpVal /= 10;
tmpE++;
}
else
{
tmpVal *= 10;
tmpE--;
}
}
return( int )tmpVal;
}
public String toShortString()
{
Long l = new Long( m_Val );
String str = l.toString();
int len = str.length() + ( int )m_E;
l = null;
str = null;
if( len > 0 )
{
return str.substring( 0, len );
}
else
{
return "0";
}
}
public String toString()
{
if( Equal( ERROR ) )
{
return "NaN";
}
Long l = new Long( m_Val );
String str = l.toString();
int len = str.length();
l = null;
if( m_E < 0L )
{
int absE = ( int )Math.abs( m_E );
if( absE < len )
{
str = String.valueOf( String.valueOf( ( new StringBuffer( String.valueOf(
String.valueOf( str.substring( 0, len - absE ) ) ) ) ).append( "." ).append(
str.substring( len - absE ) ) ) );
}
else
{
for( int i = 0; i < absE - len; i++ )
{
str = "0".concat( String.valueOf( String.valueOf( str ) ) );
}
str = "0.".concat( String.valueOf( String.valueOf( str ) ) );
}
}
else
{
for( int i = 0; ( long )i < m_E; i++ )
{
str = String.valueOf( String.valueOf( str ) ).concat( "0" );
}
}
return str;
}
public void SetValue( long l )
{
m_Val = l;
m_E = 0L;
}
public void SetValue( CFloat v )
{
m_Val = v.m_Val;
m_E = v.m_E;
}
public CFloat Add( long l )
{
CFloat t = new CFloat( l );
t = Add( t );
return t;
}
public static CFloat Add( CFloat v1, CFloat v2 )
{
return v1.Add( v2 );
}
public CFloat Add( CFloat value )
{
if( value.Equal( ZERO ) )
{
return new CFloat( this );
}
long e1 = m_E;
long e2 = value.m_E;
long v1 = m_Val;
long v2 = value.m_Val;
do
{
if( e1 == e2 )
{
break;
}
if( e1 > e2 )
{
if( Math.abs( v1 ) < 0x147ae147ae147aeL )
{
v1 *= 10;
e1--;
}
else
{
v2 /= 10;
e2++;
}
}
else
if( e1 < e2 )
{
if( Math.abs( v2 ) < 0x147ae147ae147aeL )
{
v2 *= 10;
e2--;
}
else
{
v1 /= 10;
e1++;
}
}
}
while( true );
if( v1 > ( long )0 && v2 > 0x7fffffffffffffffL - v1 ||
v1 < ( long )0 && v2 < 0x8000000000000000L - v1 )
{
v1 /= 10;
e1++;
v2 /= 10;
e2++;
}
if( v1 > ( long )0 && v2 > 0x7fffffffffffffffL - v1 )
{
return new CFloat( ERROR );
}
if( v1 < ( long )0 && v2 < 0x8000000000000000L - v1 )
{
return new CFloat( ERROR );
}
else
{
return new CFloat( v1 + v2, e1 );
}
}
public CFloat Sub( long v )
{
return Sub( new CFloat( v ) );
}
public static CFloat Sub( CFloat v1, CFloat v2 )
{
return v1.Sub( v2 );
}
public CFloat Sub( CFloat value )
{
if( value.Equal( ZERO ) )
{
return new CFloat( m_Val, m_E );
}
else
{
return Add( new CFloat( -value.m_Val, value.m_E ) );
}
}
public static CFloat Mul( CFloat v1, long v2 )
{
return v1.Mul( new CFloat( v2 ) );
}
public CFloat Mul( long value )
{
return Mul( new CFloat( value, 0L ) );
}
public static CFloat Mul( CFloat v1, CFloat v2 )
{
return v1.Mul( v2 );
}
public CFloat Mul( CFloat value )
{
long e1 = m_E;
long e2 = value.m_E;
long v1 = m_Val;
long v2 = value.m_Val;
if( value.Equal( ONE ) )
{
return new CFloat( this );
}
if( value.Equal( ZERO ) || Equal( ZERO ) )
{
return new CFloat( ZERO );
}
do
{
try
{
if( Math.abs( v2 ) > Math.abs( v1 ) )
{
if( 0x7fffffffffffffffL / Math.abs( v1 ) >= Math.abs( v2 ) )
{
break;
}
v2 /= 10;
e2++;
continue;
}
if( 0x7fffffffffffffffL / Math.abs( v2 ) >= Math.abs( v1 ) )
{
break;
}
v1 /= 10;
e1++;
}
catch( Exception e )
{
System.out.println( v1 + " " + v2 + " " + e1 + " " + e2 );
}
}
while( true );
long e = e1 + e2;
long v = v1 * v2;
return new CFloat( v, e );
}
public CFloat Div( long value )
{
return Div( new CFloat( value, 0L ) );
}
public CFloat Div( CFloat value )
{
if( value.Equal( ONE ) )
{
return new CFloat( this );
}
long e1 = m_E;
long e2 = value.m_E;
long v1 = m_Val;
if( v1 == 0L )
{
return new CFloat( ZERO );
}
long v2 = value.m_Val;
if( v2 == 0L )
{
return new CFloat( ERROR );
}
long val = 0L;
do
{
val += v1 / v2;
v1 %= v2;
if( v1 != 0L && Math.abs( val ) <= 0xcccccccccccccccL )
{
if( Math.abs( v1 ) > 0xcccccccccccccccL )
{
v2 /= 10L;
e2++;
}
else
{
v1 *= 10L;
e1--;
}
val *= 10L;
}
else
{
CFloat f = new CFloat( val, e1 - e2 );
f.RemoveZero();
return f;
}
}
while( true );
}
public void RemoveZero()
{
if( m_Val == ( long )0 )
{
return;
}
while( m_Val % ( long )10 == ( long )0 )
{
m_Val /= 10;
m_E++;
}
}
public boolean Great( long x )
{
return Great( new CFloat( x, 0L ) );
}
public boolean Great( CFloat x )
{
long e1 = m_E;
long e2 = x.m_E;
long v1 = m_Val;
long v2 = x.m_Val;
do
{
if( e1 == e2 )
{
break;
}
if( e1 > e2 )
{
if( Math.abs( v1 ) < 0x147ae147ae147aeL )
{
v1 *= 10;
e1--;
}
else
{
v2 /= 10;
e2++;
}
}
else
if( e1 < e2 )
{
if( Math.abs( v2 ) < 0x147ae147ae147aeL )
{
v2 *= 10;
e2--;
}
else
{
v1 /= 10;
e1++;
}
}
}
while( true );
return v1 > v2;
}
public boolean Less( long x )
{
return Less( new CFloat( x, 0L ) );
}
public boolean Less( CFloat x )
{
long e1 = m_E;
long e2 = x.m_E;
long v1 = m_Val;
long v2 = x.m_Val;
do
{
if( e1 == e2 )
{
break;
}
if( e1 > e2 )
{
if( Math.abs( v1 ) < 0x147ae147ae147aeL )
{
v1 *= 10;
e1--;
}
else
{
v2 /= 10;
e2++;
}
}
else
if( e1 < e2 )
{
if( Math.abs( v2 ) < 0x147ae147ae147aeL )
{
v2 *= 10;
e2--;
}
else
{
v1 /= 10;
e1++;
}
}
}
while( true );
return v1 < v2;
}
public boolean Equal( long x )
{
return Equal( new CFloat( x, 0L ) );
}
public boolean Equal( CFloat x )
{
long e1 = m_E;
long e2 = x.m_E;
long v1 = m_Val;
long v2 = x.m_Val;
do
{
if( e1 == e2 )
{
break;
}
if( e1 > e2 )
{
if( Math.abs( v1 ) < 0x147ae147ae147aeL )
{
v1 *= 10;
e1--;
}
else
{
v2 /= 10;
e2++;
}
}
else
if( e1 < e2 )
{
if( Math.abs( v2 ) < 0x147ae147ae147aeL )
{
v2 *= 10;
e2--;
}
else
{
v1 /= 10;
e1++;
}
}
}
while( true );
return v1 == v2;
}
public CFloat Neg()
{
return new CFloat( -m_Val, m_E );
}
public static CFloat Sqrt( CFloat x )
{
int sp = 0;
boolean inv = false;
if( x.Less( ZERO ) || x.Equal( ZERO ) )
{
return new CFloat( ZERO );
}
if( x.Equal( ONE ) )
{
return new CFloat( ONE );
}
if( x.Less( ONE ) )
{
x = ONE.Div( x );
inv = true;
}
for( ; x.Great( new CFloat( 16L ) ); x = x.Div( 16L ) )
{
sp++;
}
CFloat a = new CFloat( 2L );
CFloat b;
for( int i = 5; i > 0; i-- )
{
b = x.Div( a );
a = a.Add( b );
a = a.Mul( new CFloat( 5L, -1L ) );
}
while( sp > 0 )
{
sp--;
a = a.Mul( 4L );
}
if( inv )
{
a = ONE.Div( a );
}
b = null;
return a;
}
static
{
//ITNUM = 5;
PI = new CFloat( 0x11db9e76a2483L, -14L );
PIdiv2 = PI.Div( 2L );
PIdiv4 = PIdiv2.Div( 2L );
PIdiv6 = PIdiv2.Div( 3L );
PIdiv12 = PIdiv6.Div( 2L );
PImul2 = PI.Mul( 2L );
PImul4 = PI.Mul( 4L );
}
}
(方案二)
你可以直接用long类型,运算时默认最后有几位"表示"小数,比如定义3位小数位,12345表示12.345。在处理结果时考虑好小数位就可以了