关于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。在处理结果时考虑好小数位就可以了