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