| 关于j2me中浮点问题的解决方案 |
|
|
|
|
Author: 一滴蔚蓝色 | Date: 2008-04-12 | View: 644
|
开发技术 -
程序设计
| ||||
|
(方案一) 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。在处理结果时考虑好小数位就可以了 本文关键字: j2me 浮点 阅读数: 645 | 打印 | E-mail
|
||||||||
| (j2me研发笔记-键盘响应) < 上一篇 | 下一篇 > (简单的AI实现) |
|---|