J2ME(MIDP1.0)计算float,int,long数值的平方根

来源:互联网 发布:centos chrome 编辑:程序博客网 时间:2024/06/11 19:43

     最近看到了做J2ME开发的朋友们有人询问如何在MIDP1.0环境下进行开平方运算。正好自己对这个问题有一个比较好的解决办法,所以在这里和大家分享一下。

    其实办法也比较简单,运算的过程对资源的占用也很少。具体的方法如下:

 /**
     * 得到算术平方根。
     * @param num    String        要开平方的数的字符串形式
     * @param baoliu int           平方根中保留的小数的位数
     * @return int[]               返回值,int[0]是平方根的整数部分,int[1]是平方根的小数部分
     */
    public static int[] sqrt(String num, int baoliu) {
        int index4Dot = num.indexOf(".");
        int zheng = 0, xiao = 0, leftZeroNum = 0;
        if (index4Dot >= 0) {
            String zhengStr = num.substring(0, index4Dot); //整数部分
            String xiaoStr = num.substring(index4Dot + 1, num.length()); //小数部分
            zheng = Integer.parseInt(zhengStr);
            xiao = Integer.parseInt(xiaoStr);
            while ("0".equals(num.substring(index4Dot + 1 + leftZeroNum,
                index4Dot + 2 + leftZeroNum))) {
                leftZeroNum++;
            }
        } else {
            zheng = Integer.parseInt(num);
        }
        if (baoliu > (19 - getAmount(zheng)) / 2) {
            baoliu = (19 - getAmount(zheng)) / 2;
        }
        long square = decimalMoveLeft(zheng, baoliu * 2);
        square += getLeft(xiao, baoliu * 2 - leftZeroNum);
        int amount = getAmount(square);
        int count = 1, beijianshu, yushu, shang;
        int flag = amount % 2 == 0 ? 2 : 1;
        int total = amount % 2 == 0 ? amount / 2 : amount / 2 + 1;
        beijianshu = (int) getLeft(square, flag);
        shang = getMaxPowerRoot(beijianshu);
        yushu = beijianshu - shang * shang;
        while (count < total) {
            beijianshu = yushu * 100 + (int) (getLeft(square,
                count * 2 + flag) % 100);
            shang = getMaxShang(beijianshu, shang);
            yushu = beijianshu - (shang / 10 * 20 + shang % 10) * (shang % 10);
            count++;
        }
        int[] result = new int[2];
        result[0] = (int) (shang / decimalMoveLeft(1, baoliu));
        result[1] = (int) (shang % decimalMoveLeft(1, baoliu));
        return result;
    }

    /**
     * 得到最大商数
     * @param yushu int
     * @param shang int
     * @return int
     */
    public static int getMaxShang(int yushu, int shang) {
        int num = 1;
        while (yushu >= (shang * 20 + num) * num) {
            num++;
        }
        return shang * 10 + num - 1;
    }

    /**
     * 得到num(仅限两位数以内)的平方根。例如:“88”得到“9”;“3”得到“1”
     * @param num int
     * @return int
     */
    public static int getMaxPowerRoot(int num) {
        if (num < 4) {
            return 1;
        }
        int root = 2;
        while (num >= root * root) {
            root++;
        }
        return root - 1;
    }

    /**
     * 取得 num 左边的 wei 位数字。例如(12345,2)返回“12”;(12345,8)返回“12345000”
     * @param num long      要运算的数字
     * @param wei int       位数
     * @return long
     */
    public static long getLeft(long num, int wei) {
        int amount = getAmount(num);
        if (amount > wei) {
            return decimalMoveRight(num, amount - wei);
        } else if (amount < wei) {
            return decimalMoveLeft(num, wei - amount);
        } else {
            return num;
        }
    }

    /**
     * 取得 num 的位数。例如:“0”是0位,“2”是1位,“12523”是5位
     * @param num long     要统计位数的数字
     * @return int
     */
    public static int getAmount(long num) {
        int count = 0;
        if (num > 0) {
            count++;
        } while (num > 10) {
            num /= 10;
            count++;
        }
        return count;
    }

    /**
     * 十进制左移
     * @param num long     要左移的数
     * @param left int     左移的位数
     * @return long
     */
    public static long decimalMoveLeft(long num, int left) {
        while (left > 0) {
            num *= 10;
            left--;
        }
        return num;
    }

    /**
     * 十进制右移
     * @param num long      要右移的数
     * @param right int     右移的位数
     * @return long
     */
    public static long decimalMoveRight(long num, int right) {
        while (right > 0) {
            num /= 10;
            right--;
        }
        return num;
    }

使用一个MIDlet调用测试一下:

 protected void startApp() throws MIDletStateChangeException {
        int[] root = new int[2];
        root = sqrt("3", 7);
        System.out.println("3  保留7位:/t" + root[0] + "." + root[1]);
        root = sqrt("19", 7);
        System.out.println("19 保留7位:/t" + root[0] + "." + root[1]);
        root = sqrt("10.987", 7);
        System.out.println("10.987 保留7位:/t" + root[0] + "." + root[1]);
        root = sqrt("1000", 7);
        System.out.println("1000 保留7位:/t" + root[0] + "." + root[1]);
        root = sqrt("89798768.0987878", 7);
        System.out.println("89798768.0987878 保留7位:/t" + root[0] + "." + root[1]);
    }

输出如下:

3 保留7位:                    1.7320508
19 保留7位:                  4.3588989
10.987 保留7位:          3.3146643
1000 保留7位:             31.6227760
89798768.0987878 保留7位:         9476.22110

该方法占用CPU的时间很少,其中对字符串的解析占用了大部分的时间使用下面的方法代替一下,就会发现,CPU时间只是原来的1/3左右,呵呵。

 /**
     * 得到算术平方根。
     * @param zheng int            要开方的数的整数部分
     * @param xiao int             要开方的数的小数部分
     * @param leftZeroNum int      小数部分左边的“0”的个数。例如“34.00932”中的小数点后面的两个“0”
     * @param baoliu int           平方根中保留的小数的位数
     * @return int[]               返回值,int[0]是平方根的整数部分,int[1]是平方根的小数部分
     */
    public static int[] sqrt(int zheng, int xiao, int leftZeroNum, int baoliu) {
        int[] result = new int[2];
        if (baoliu > (19 - getAmount(zheng)) / 2) {
            baoliu = (19 - getAmount(zheng)) / 2;
        }
        long square = decimalMoveLeft(zheng, baoliu * 2);
        square += getLeft(xiao, baoliu * 2 - leftZeroNum);
        int amount = getAmount(square);
        int count = 1, beijianshu, yushu, shang;
        int flag = amount % 2 == 0 ? 2 : 1;
        int total = amount % 2 == 0 ? amount / 2 : amount / 2 + 1;
        beijianshu = (int) getLeft(square, flag);
        shang = getMaxPowerRoot(beijianshu);
        yushu = beijianshu - shang * shang;
        while (count < total) {
            beijianshu = yushu * 100 + (int) (getLeft(square,
                count * 2 + flag) % 100);
            shang = getMaxShang(beijianshu, shang);
            yushu = beijianshu - (shang / 10 * 20 + shang % 10) * (shang % 10);
            count++;
        }
        result[0] = (int) (shang / decimalMoveLeft(1, baoliu));
        result[1] = (int) (shang % decimalMoveLeft(1, baoliu));
        return result;
    }

对于这个方法,大家可以讨论一下。我的MSN:cuilichen@hotmail.com

原创粉丝点击