⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 float.java

📁 实现了一个基于j2me移动gps定位系统
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        return result;
    }

    /**
     * Returns the correctly rounded positive square root of a double value.
     * Special cases: If the argument is NaN or less than zero, then the result
     * is NaN. If the argument is positive infinity, then the result is positive
     * infinity. If the argument is positive zero or negative zero, then the
     * result is the same as the argument. Otherwise, the result is the double
     * value closest to the true mathematical square root of the argument value
     * 
     * @param x
     *            Float - a value
     * @return Float - the positive square root of a. If the argument is NaN or
     *         less than zero, the result is NaN
     */
    private static Float sqrt(Float x) {
        int sp = 0;
        boolean inv = false;
        Float a, b;
        //
        if (x.Less(ZERO))
            return new Float(ERROR);
        if (x.Equal(ZERO))
            return new Float(ZERO);
        if (x.Equal(ONE))
            return new Float(ONE);
        // argument less than 1 : invert it
        if (x.Less(ONE)) {
            x = ONE.Div(x);
            inv = true;
        }
        //
        long e = x.m_E / 2;
        // exponent compensation
        Float tmp = new Float(x.m_Val, x.m_E - e * 2);
        // process series of division by 16 until argument is <16
        while (tmp.Great(new Float(16L))) {
            sp++;
            tmp = tmp.Div(16L);
        }
        // initial approximation
        a = new Float(2L);
        // Newtonian algorithm
        for (int i = ITNUM; i > 0; i--) {
            b = tmp.Div(a);
            a = a.Add(b);
            a = a.Div(2L);
        }
        // multiply result by 4 : as much times as divisions by 16 took place
        while (sp > 0) {
            sp--;
            a = a.Mul(4L);
        }
        // exponent compensation
        a.m_E += e;
        // invert result for inverted argument
        if (inv)
            a = ONE.Div(a);
        return a;
    }

    /**
     * Returns the trigonometric tangent of an angle. Special cases: If the
     * argument is NaN or an infinity, then the result is NaN. If the argument
     * is zero, then the result is a zero with the same sign as the argument. A
     * result must be within 1 ulp of the correctly rounded result. Results must
     * be semi-monotonic
     * 
     * @param x
     *            Float - an angle, in radians
     * @return Float - the tangent of the argument
     */
    static public Float tan(Float x) {
        Float c = cos(x);
        if (c.Equal(ZERO))
            return new Float(ERROR);
        return (sin(x).Div(c));
    }

    /**
     * Returns a new Float object initialized to the value represented by the
     * specified String
     * 
     * @param str
     *            String - the string to be parsed
     * @param radix
     *            int - basement of number
     * @return Float - the Float object represented by the string argument
     */
    static public Float parse(String str, int radix) {
        // Abs
        boolean neg = false;
        if (str.charAt(0) == '-') {
            str = str.substring(1);
            neg = true;
        }
        //
        int pos = str.indexOf(".");
        long exp = 0;
        // Find exponent position
        int pos2 = str.indexOf('E');
        if (pos2 == -1)
            pos2 = str.indexOf('e');
        //
        if (pos2 != -1) {
            String tmp = str.substring(pos2 + 1);
            exp = Long.parseLong(tmp);
            str = str.substring(0, pos2);
        }
        //
        if (pos != -1) {
            for (int m = pos + 1; m < str.length(); m++) {
                if (Character.isDigit(str.charAt(m)))
                    exp--;
                else
                    break;
            }
            str = str.substring(0, pos) + str.substring(pos + 1);
            while (str.length() > 1 && str.charAt(0) == '0'
                    && str.charAt(1) != '.')
                str = str.substring(1);
        }
        //
        long result = 0L;
        int len = str.length();
        //
        StringBuffer sb = new StringBuffer(str);
        while (true) {
            // Long value can't have length more than 20
            while (len > 20) {
                // Very large number for Long
                sb = sb.deleteCharAt(len - 1);
                // Compensation of removed zeros
                if (len < pos || pos == -1)
                    exp++;
                //
                len--;
            }
            //
            try {
                result = Long.parseLong(sb.toString(), radix);
                if (neg)
                    result = -result;
                break;
            } catch (Exception e) {
                // Very large number for Long
                sb = sb.deleteCharAt(len - 1);
                // Compensation of removed zeros
                if (len < pos || pos == -1)
                    exp++;
                //
                len--;
            }
        }
        sb = null;
        //
        Float newValue = new Float(result, exp);
        newValue.RemoveZero();
        return newValue;
    }

    /**
     * Returns the arc cosine of an angle, in the range of 0.0 through pi.
     * Special case: If the argument is NaN or its absolute value is greater
     * than 1, then the result is NaN. A result must be within 1 ulp of the
     * correctly rounded result. Results must be semi-monotonic
     * 
     * @param x
     *            Float - the value whose arc cosine is to be returned
     * @return Float - the arc cosine of the argument
     */
    static public Float acos(Float x) {
        Float f = asin(x);
        if (f.isError())
            return f;
        return PIdiv2.Sub(f);
    }

    /**
     * Returns the arc sine of an angle, in the range of -pi/2 through pi/2.
     * Special cases: If the argument is NaN or its absolute value is greater
     * than 1, then the result is NaN. If the argument is zero, then the result
     * is a zero with the same sign as the argument. A result must be within 1
     * ulp of the correctly rounded result. Results must be semi-monotonic
     * 
     * @param x
     *            Float - the value whose arc sine is to be returned
     * @return Float - the arc sine of the argument
     */
    private static Float asin(Float x) {
        if (x.Less(ONE.Neg()) || x.Great(ONE))
            return new Float(ERROR);
        if (x.Equal(ONE.Neg()))
            return PIdiv2.Neg();
        if (x.Equal(ONE))
            return PIdiv2;
        return atan(x.Div(sqrt(ONE.Sub(x.Mul(x)))));
    }

    /**
     * Returns the arc tangent of an angle, in the range of -pi/2 through pi/2.
     * Special cases: If the argument is NaN, then the result is NaN. If the
     * argument is zero, then the result is a zero with the same sign as the
     * argument. A result must be within 1 ulp of the correctly rounded result.
     * Results must be semi-monotonic
     * 
     * @param x
     *            Float - the value whose arc tangent is to be returned
     * @return Float - the arc tangent of the argument
     */
    private static Float atan(Float x) {
        boolean signChange = false;
        boolean Invert = false;
        int sp = 0;
        Float x2, a;
        // check up the sign change
        if (x.Less(ZERO)) {
            x = x.Neg();
            signChange = true;
        }
        // check up the invertation
        if (x.Great(ONE)) {
            x = ONE.Div(x);
            Invert = true;
        }
        // process shrinking the domain until x<PI/12
        while (x.Great(PIdiv12)) {
            sp++;
            a = x.Add(SQRT3);
            a = ONE.Div(a);
            x = x.Mul(SQRT3);
            x = x.Sub(ONE);
            x = x.Mul(a);
        }
        // calculation core
        x2 = x.Mul(x);
        a = x2.Add(new Float(14087812, -7));
        a = new Float(55913709, -8).Div(a);
        a = a.Add(new Float(60310579, -8));
        a = a.Sub(x2.Mul(new Float(5160454, -8)));
        a = a.Mul(x);
        // process until sp=0
        while (sp > 0) {
            a = a.Add(PIdiv6);
            sp--;
        }
        // invertation took place
        if (Invert)
            a = PIdiv2.Sub(a);
        // sign change took place
        if (signChange)
            a = a.Neg();
        //
        return a;
    }

    /**
     * Converts rectangular coordinates (x,�y) to polar (r,�theta). This method
     * computes the phase theta by computing an arc tangent of y/x in the range
     * of -pi to pi. Special cases: If either argument is NaN, then the result
     * is NaN. If the first argument is positive zero and the second argument is
     * positive, or the first argument is positive and finite and the second
     * argument is positive infinity, then the result is positive zero. If the
     * first argument is negative zero and the second argument is positive, or
     * the first argument is negative and finite and the second argument is
     * positive infinity, then the result is negative zero. If the first
     * argument is positive zero and the second argument is negative, or the
     * first argument is positive and finite and the second argument is negative
     * infinity, then the result is the double value closest to pi. If the first
     * argument is negative zero and the second argument is negative, or the
     * first argument is negative and finite and the second argument is negative
     * infinity, then the result is the double value closest to -pi. If the
     * first argument is positive and the second argument is positive zero or
     * negative zero, or the first argument is positive infinity and the second
     * argument is finite, then the result is the double value closest to pi/2.
     * If the first argument is negative and the second argument is positive
     * zero or negative zero, or the first argument is negative infinity and the
     * second argument is finite, then the result is the double value closest to
     * -pi/2. If both arguments are positive infinity, then the result is the
     * double value closest to pi/4. If the first argument is positive infinity
     * and the second argument is negative infinity, then the result is the
     * double value closest to 3*pi/4. If the first argument is negative
     * infinity and the second argument is positive infinity, then the result is
     * the double value closest to -pi/4. If both arguments are negative
     * infinity, then the result is the double value closest to -3*pi/4. A
     * result must be within 2 ulps of the correctly rounded result. Results
     * must be semi-monotonic
     * 
     * @param y
     *            Float - the ordinate coordinate
     * @param x
     *            Float - the abscissa coordinate
     * @return Float - the theta component of the point (r,�theta) in polar
     *         coordinates that corresponds to the point (x,�y) in Cartesian
     *         coordinates
     */
    static public Float atan2(Float y, Float x) {
        // if x=y=0
        if (y.Equal(ZERO) && x.Equal(ZERO))
            return new Float(ZERO);
        // if x>0 atan(y/x)
        if (x.Great(ZERO))
            return atan(y.Div(x));
        // if x<0 sign(y)*(pi - atan(|y/x|))
        if (x.Less(ZERO)) {
            if (y.Less(ZERO))
                return Float.PI.Sub(atan(y.Div(x))).Neg();
            else
                return Float.PI.Sub(atan(y.Div(x).Neg()));
        }
        // if x=0 y!=0 sign(y)*pi/2
        if (y.Less(ZERO))
            return PIdiv2.Neg();
        else
            return new Float(PIdiv2);
    }

    // precise
    // x=-35 diff=1.48%
    // x=-30 diff=0.09%
    // x=30 diff=0.09%
    // x=31 diff=0.17%
    // x=32 diff=0.31%
    // x=33 diff=0.54%
    // x=34 diff=0.91%
    // x=35 diff=1.46%
    /**
     * Returns Euler's number e raised to the power of a double value. Special
     * cases: If the argument is NaN, the result is NaN. If the argument is
     * positive infinity, then the result is positive infinity. If the argument
     * is negative infinity, then the result is positive zero. A result must be
     * within 1 ulp of the correctly rounded result. Results must be
     * semi-monotonic
     * 
     * @param x
     *            Float - the exponent to raise e to
     * @return Float - the value e^x, where e is the base of the natural
     *         logarithms
     */
    private static Float exp(Float x) {
        if (x.Equal(ZERO))
            return new Float(ONE);
        //
        Float f = new Float(ONE);
        long d = 1;
        Float k = null;
        boolean isless = x.Less(ZERO);
        if (isless)
            x = x.Neg();
        k = new Float(x).Div(d);
        //
        for (long i = 2; i < 50; i++) {
            f = f.Add(k);
            k = k.Mul(x).Div(i);
        }
        //
        if (isless)
            return ONE.Div(f);
        else
            return f;
    }

    // precise
    // x=25 diff=0.12%
    // x=30 diff=0.25%
    // x=35 diff=0.44%
    // x=40 diff=0.67%
    /**
     * Internal log subroutine
     * 
     * @param x
     *            Float

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -