www.pudn.com > 货币交换.rar > Converter.java~6~


/*
 *
 * Copyright 2004 FlashMan.Ncuhome.com Inc. All Rights Reserved.
 *
 * 我的第一个J2ME程序习作
 * 用于在支持J2ME以及MIDP1.0的手机上进行不同货币单位的汇率换算(PS:其实是用于友人的作业)
 * 本程序共有3个类,其中2个功能类
 * Math类用来处理浮点数的四则运算
 * MyInput类生成输入框,为的是更方便的输入数值.
 *
 * 本例中我有两个问题
 *   1.List组件的setSelectedIndex(int elementNum,boolean selected)方法为何不能将
 *     光标定位在指定的列上
 *   2.在这个程序中我自定义了一个输入框类,能不能用不太麻烦的方法使它能像系统自带
 *     的输入框一样支持光标显示
 *
 * 而且还有好些不足之处
 *   1.用户不可以自已添加/删除货币单位及汇率,仅能通过联网更新
 *   2.从菜单中选择Restore Rate时不经用户确认就将数据库复位
 *   3.代码不够优化(比如:用了太多的Command对象引用)
 *
 * 还有一点需要提醒一下的是通过联网更新汇率的方法只在Jbuilder9自带的J2ME Wireless Toolkit 1.0
 * 能正常连网,如果是J2ME Wireless Toolkit 2.1的SDK就会发现点enter准备更新的时候它会"善意"的告诉
 * 程序想要访问网络,这将会产生某些费用,然后给你两个选择Yes/No.再然后你就会发现它已经死掉了,不论
 * 你选择的是YesOrNo.所以我想最好还是安安心心的用Toolkit 1.0SDK进行调试吧
 *
 * 有任何建议和意见请发邮件至itfeihu@163.com
 * 也可通过我的早期作品闪狐超酷Flash留言板给我留言 flashbook.ncuhome.com
 * 同时欢迎访问我的个人主页 flashman.ncuhome.com
 * 当然也欢迎访问我们的校园网站"南昌大学家园网"
 *
 *                                                                    2004-6-9
 */

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;
import javax.microedition.io.*;
import java.io.*;

public class Converter
    extends MIDlet
    implements CommandListener {

  String dbName = "Converter"; //数据库名

  String CurrencyName[]; //用于存放货币单位的数组
  String Rate[][]; //用于存放货币之间的交叉汇率

  String money_s = "0"; //源货币
  String money_t = "0"; //目标货币
  int source = 0; //源货币单位在数组中的位置
  int object = 0; //目标货币单位在数组中的位置
  int selected = 0; //当前选择的菜单项位置
  String updateURL; //提供更新汇率的网址

  Alert alert = new Alert("Alert"); //定义一个用于提示信息的Alert
  Display display; //定义屏幕对象
  MyInput myInput; //定义一个输入框
  Math math = new Math(); //浮点运算类

  public Converter() {
    alert.setType(AlertType.WARNING); //设置alert的类型
    alert.setTimeout(3000); //alert的显示时间
    display = Display.getDisplay(this); //获得对屏幕控制的引用
  }

  public void startApp() {
    openDb(); //从数据库中获取汇率和恢复上一次正常退出时的状态
    main(); //运行界面
    renewVar(); //更新所有的变量状态
  }

  public void pauseApp() {}

  public void destroyApp(boolean unconditional) {}

  List list; //定义一个List组件用于显示选单
  Command cmdExit; //定义一个Command按纽组件
  void main() {

    cmdExit = new Command("Exit", Command.EXIT, 0); //生成Command对象(显示内容,按纽型态,显示优先级)
    list = new List("Rate Converter", Choice.IMPLICIT); //生成List(主选单)(标题,型态[单选])

    //追加各个选单
    list.append("From " + CurrencyName[source], null);
    list.append("To " + CurrencyName[object], null);
    list.append("Rate 1:" + Rate[source][object], null);
    list.append("Valuta:" + money_s, null);
    list.append("Result:" + money_t, null);

    //追回系统选单
    list.addCommand(cmdExit);
    list.addCommand(new Command("Update rate", Command.SCREEN, 0));
    list.addCommand(new Command("Restore rate", Command.SCREEN, 0));
    list.addCommand(new Command("About", Command.SCREEN, 0));

    list.setCommandListener(this); //设置事件监听

    list.setSelectedIndex(selected, true);
    //设置光标定位在上次操作选定的选单
    //但不知为何就是不行,明明是说设成true的,这是我的问题之一

    display.setCurrent(list); //显示选单

  }

  //选择源货币单位
  List sourceList;
  Command sourceEnter;
  Command sourceCancel;
  void SelectSource() {

    sourceList = new List("Choose Source", Choice.EXCLUSIVE);
    sourceEnter = new Command("Enter", Command.OK, 0);
    sourceCancel = new Command("Cancel", Command.CANCEL, 1);

    for (int I = 0; I < CurrencyName.length; I++) { //将货币单位全部添至选单
      sourceList.append(CurrencyName[I], null); //null这个位置的参数可以用来显示图像
    }

    //添加按纽及设置事件监听
    sourceList.addCommand(sourceEnter);
    sourceList.addCommand(sourceCancel);
    sourceList.setCommandListener(this);

    sourceList.setSelectedIndex(source, true);
    //设置光标定位在上次操作选定的选单,但和前面一样无效
    display.setCurrent(sourceList);

  }

  //选择目标货币单位
  List objectList;
  Command objectEnter;
  Command objectCancel;
  void SelectObject() {

    //同上
    objectList = new List("Choose Object", Choice.EXCLUSIVE);
    objectEnter = new Command("Enter", Command.OK, 0);
    objectCancel = new Command("Cancel", Command.CANCEL, 1);

    for (int I = 0; I < CurrencyName.length; I++) {
      objectList.append(CurrencyName[I], null);
    }

    objectList.addCommand(objectEnter);
    objectList.addCommand(objectCancel);
    objectList.setCommandListener(this);

    objectList.setSelectedIndex(object, true);
    //设置光标定位在上次操作选定的选单,照样无效
    display.setCurrent(objectList);

  }

  Command setRateEnter;
  Command setRateCancel;
  void setRate() { //修改汇率

    myInput = new MyInput(34, 53, Rate[source][object]); //在x:34,y:53的位置显示输入框,并传递原汇率值
    setRateEnter = new Command("Enter", Command.OK, 0);
    myInput.addCommand(setRateEnter);

    setRateCancel = new Command("Cancel", Command.CANCEL, 1);
    myInput.addCommand(setRateCancel);

    display.setCurrent(myInput);
    myInput.setCommandListener(this);

  }

  Command inputEnter;
  Command inputCancel;
  void inputMoney() { //输入货币金额

    myInput = new MyInput(34, 69); //指定位置显示一个空白的输入框
    inputEnter = new Command("Enter", Command.OK, 0);
    myInput.addCommand(inputEnter);

    inputCancel = new Command("Cancel", Command.CANCEL, 1);
    myInput.addCommand(inputCancel);

    display.setCurrent(myInput);
    myInput.setCommandListener(this);

  }

  Command reverseEnter;
  Command reverseCancel;
  void reverseMoney() { //反向金额输入

    myInput = new MyInput(33, 85); //指定位置显示一个空白的输入框
    reverseEnter = new Command("Enter", Command.OK, 0);
    myInput.addCommand(reverseEnter);

    reverseCancel = new Command("Cancel", Command.CANCEL, 1);
    myInput.addCommand(reverseCancel);

    display.setCurrent(myInput);
    myInput.setCommandListener(this);

  }

  TextField input;
  Command updateEnter;
  Command updateCancel;
  void updateRate() { //连网更新数据

    Form form = new Form("Update rate");

    updateEnter = new Command("Enter", Command.OK, 0);
    form.addCommand(updateEnter);

    updateCancel = new Command("Cancel", Command.CANCEL, 0);
    form.addCommand(updateCancel);

    input = new TextField("Update's URL:", updateURL, 100, TextField.URL);
    form.append(input);

    form.setCommandListener(this);
    display.setCurrent(form);

  }

  public void commandAction(Command c, Displayable s) { //用于响应所有的操作事件

    if (c.getLabel() == "Restore rate") { //初始化数据库
      dbInitialize();
      startApp();
      return;
    }

    if (c.getLabel() == "Update rate") { //汇率更新界面
      updateRate();
      return;
    }

    if (c.getLabel() == "About") { //汇率更新界面
      alert.setString("Copyright(c)2004 FlashMan.Ncuhome.Com"); //提示无效的URL链接或无效的数据页
      alert.setTimeout(6000);
      display.setCurrent(alert);
      alert.setTimeout(3000);
      return;
    }

    if (c == updateEnter) { //汇率主更新程序(汇率更新界面)
      StartUpdate();
      return;
    }

    if (c == updateCancel) { //取消更新(汇率更新界面)
      main();
      return;
    }

    if (c == sourceEnter) { //源货币单位选择
      source = sourceList.getSelectedIndex();
      money_t = math.Multiplication(money_s, Rate[source][object]); //计算货币单位变更后的转换结果
      main();
      return;
    }

    if (c == sourceCancel) { //取消选择源货币(源货币单位选择界面)
      main();
      return;
    }

    if (c == objectEnter) { //目标币单位选择
      object = objectList.getSelectedIndex();
      money_t = math.Multiplication(money_s, Rate[source][object]); //计算货币单位变更后的转换结果
      main();
      return;
    }

    if (c == objectCancel) { //取消选择目标货币(源货币单位选择界面)
      main();
      return;
    }

    if (c == cmdExit) { //正常退出
      saveDb(); //将各变量状态保存至数据库
      notifyDestroyed();
      return;
    }

    if (c == inputEnter) { //转换值输入
      money_s = myInput.value.toString(); //myInput是自定义的输入框类
      if (money_s.length() < 1) {
        money_s = "0";
      }
      money_t = math.Multiplication(money_s, Rate[source][object]); //计算转换结果
      main();
      return;
    }

    if (c == inputCancel) { //取消输入(转换值)
      main();
      return;
    }

    if (c == reverseEnter) { //在结果中输入(反向转换)
      money_t = myInput.value.toString();
      if (money_s.length() < 1) {
        money_s = "0";
      }
      money_s = math.Division(money_t, Rate[source][object]); //计算转换结果
      main();
      return;
    }

    if (c == reverseCancel) { //取消输入(反向转换)
      main();
      return;
    }

    if (c == setRateEnter) { //设定已选定的源/目标货币之间的汇率

      if (CurrencyName[source] != CurrencyName[object]) {
        ; //如果源货币等于目标货币则不更新汇率(得保持为1:1)
        Rate[source][object] = myInput.value.toString(); //更新汇率
        Rate[object][source] = math.Division("1", Rate[source][object]); //反向更新汇率
        money_t = math.Multiplication(money_s, Rate[source][object]); //更新结果
      }
      main();
      return;
    }

    if (c == setRateCancel) { //取消汇率设定
      main();
      return;
    }

    switch (list.getSelectedIndex()) { //根据选定的选单进行相应的操作
      case 0:
        selected = 0;
        SelectSource(); //选择源货币单位
        break;
      case 1:
        selected = 1;
        SelectObject(); //选择目标货币单位
        break;
      case 2:
        selected = 2;
        setRate(); //设定汇率
        break;
      case 3:
        selected = 3;
        inputMoney(); //输入转换值
        break;
      case 4:
        selected = 4;
        reverseMoney(); //反向转换输入值
        break;
    }

  }

  void openDb() { //从数据库中获取汇率和恢复上一次正常退出时的状态

    try {
      RecordStore rs = RecordStore.openRecordStore(dbName, false);
      /*
       定义数据库的引用对象
       第二个参数如果是true代表如果指定的数据库不存在,则系统将自动建立一个新的数据库
       反之则抛出RecordStoreNotFoundException异常
       */

      byte bytes[];
      String str;

      bytes = rs.getRecord(1); //取出第一行记录,本程序将其设置的是货币单位
      str = new String(bytes, 0, bytes.length); //将取出的bytes型数据转成字符型
      str = str.trim(); //剔除空行
      CurrencyName = newArray(str, ","); //更新一维数组变量CurrencyName

      bytes = rs.getRecord(2); //同上,汇率
      str = new String(bytes, 0, bytes.length);
      str = str.trim();
      Rate = newArrayPlanar(str, "|", ","); //更新二维数组变量Rate

      bytes = rs.getRecord(3); //同上,程序状态
      str = new String(bytes, 0, bytes.length);
      str = str.trim();
      /*更新最后一次正常退出时的程序状态,如:
              str="50,413.5,1,2,0,http://localhost/rate.asp"
              需用newArray将其转换成数组
       */
      String tmpArray[] = newArray(str, ",");
      money_s = tmpArray[0];
      money_t = tmpArray[1];
      source = Integer.parseInt(tmpArray[2]);
      object = Integer.parseInt(tmpArray[3]);
      selected = Integer.parseInt(tmpArray[4]);
      updateURL = tmpArray[5];

      rs.closeRecordStore(); //关闭数据库对象

    }
    catch (RecordStoreException ex) { //捕捉到错误异常(第一次运行的时候数据库不存在)
      dbInitialize(); //初始化数据库
      startApp(); //重新开始程序
    }

  }

  void saveDb() { //保存程序运行状态

    renewVar(); //更新变量

    try {
      RecordStore rs = RecordStore.openRecordStore(dbName, true);

      byte bytes[];

      //字符串得转成Byte型再写入数据库
      bytes = newArrayByte(defCurrencyName);
      rs.setRecord(1, bytes, 0, bytes.length);
      bytes = newArrayByte(defRate);
      rs.setRecord(2, bytes, 0, bytes.length);
      bytes = newArrayByte(defOperation);
      rs.setRecord(3, bytes, 0, bytes.length);

      rs.closeRecordStore();

//       System.out.println("Database " + dbName + "Save Seucceed!");

    }
    catch (RecordStoreException e) {
    }
  }

  //用于初始状态值
  String defCurrencyName;
  String defRate;
  String defOperation;

  void dbInitialize() { //初始化数据库

    //初始状态值
    defCurrencyName = "Pound,Dollar,RMB,ECU";
    defRate = "1,1.81,15.02,1.497"
        + "|0.55,1,8.27,0.825"
        + "|0.067,0.12,1,0.1"
        + "|0.668,1.21,10.035,1";
    defOperation = "0,0,0,0,0,http://localhost/rate.asp";

    try {
      RecordStore.deleteRecordStore(dbName); //管它有没有数据库,删了再说
    }
    catch (RecordStoreException ex) {
    }

    try {
      //删了再建一个新的,现在这里的参数用了true,也就是数据库不存在的话系统就会帮你建一个.
      RecordStore rs = RecordStore.openRecordStore(dbName, true);

      byte bytes[];

      //将初始数据存进数据库
      bytes = newArrayByte(defCurrencyName);
      rs.addRecord(bytes, 0, bytes.length);
      bytes = newArrayByte(defRate);
      rs.addRecord(bytes, 0, bytes.length);
      bytes = newArrayByte(defOperation);
      rs.addRecord(bytes, 0, bytes.length);

      rs.closeRecordStore();

//        System.out.println("Database " + dbName + "Initialize Seucceed!");

    }
    catch (RecordStoreException ex) {
    }

  }

  void renewVar() { //更新变量信息

    defCurrencyName = "";
    defRate = "";
    defOperation = "";

    for (int I = 0; I < CurrencyName.length; I++) { //更新货币单位
      defCurrencyName += CurrencyName[I];
      if (I < CurrencyName.length - 1) {
        defCurrencyName += ",";
      }
    }

    for (int I = 0; I < Rate.length; I++) { //更新汇率
      for (int J = 0; J < Rate[I].length; J++) {
        defRate += Rate[I][J];
        if (J < Rate[I].length - 1) {
          defRate += ",";
        }
      }
      if (I < Rate.length - 1) {
        defRate += "|";
      }
    }

    //更新状态
    defOperation += money_s + ",";
    defOperation += money_t + ",";
    defOperation += source + ",";
    defOperation += object + ",";
    defOperation += selected + ",";
    defOperation += updateURL;

  }

  void StartUpdate() { //联网更新汇率

    try {
      //从指定网址读取汇率值
      updateURL = input.getString();
      HttpConnection hc = (HttpConnection) Connector.open(updateURL); //生成连接对像
      DataInputStream dis = new DataInputStream(hc.openInputStream()); //获取输入流

      String content = "";
      int ic;
      while ( (ic = dis.read()) != -1) { //读取一行
        if (ic == 13) {
          dis.read();
          break;
        }
        content += (char) ic; //累加读取的字符
      }
      if (content.compareTo("RateData") == 0) { //如果第一行不是RateData则该页面不是有效的汇率数据

        content = "";
        while ( (ic = dis.read()) != -1) {
          if (ic == 13) {
            dis.read();
            break;
          }
          content += (char) ic;
        }
        CurrencyName = newArray(content, ","); //更新货币单位

        content = "";
        while ( (ic = dis.read()) != -1) {
          if (ic == 13) {
            dis.read();
            break;
          }
          content += (char) ic;
        }
        Rate = newArrayPlanar(content, "|", ","); //更新汇率

        alert.setString("Update rate succeed!"); //提示更新成功
        display.setCurrent(alert);

      }
      else {
        alert.setString("Invalid URL or files!"); //提示无效的URL链接或无效的数据页
        display.setCurrent(alert);
      }

    }
    catch (Exception e) {
      alert.setString("Connecting field!"); //提示联接失败
      display.setCurrent(alert);
    }

  }

  static String[] newArray(String Str, String sign) {
    /*
     以分隔符划分生成一维数组
     其实就等于split函数,我当时翻的一本书叫<>,里面介绍的String类
     竟然找不到split这个函数,结果导致我错误的认为"Java居然不提供split",然后就傻傻
     的自己写了一个同样功能的函数
     这个错误还是今天整理这个程序的时候想起来查了一下SDK才发现的
     不过还好这个功能并不复杂,自己写了也没花什么功夫,不过J2ME不支持浮点运算,这可写
     死我了.
     */

    int point = 1;
    int incept = 0;
    int count = 0;

    while (point > 0) {
      point = Str.indexOf(sign, point);
      point += 1;
      incept = point;
      count += 1;
    }
    String tmpArray[] = new String[count]; //确定数组大小

    //复位初始位置
    point = 1;
    incept = 0;
    int I = 0;
    while (point > 0) {

      point = Str.indexOf(sign, point);
      point += 1;

      if (point != 0) { //数组元素赋值
        tmpArray[I] = Str.substring(incept, point - 1);
      }
      else {
        tmpArray[I] = Str.substring(incept);
      }

      I++;
      incept = point;
    }

    return tmpArray;
  }

  static String[][] newArrayPlanar(String Str, String firstSign,
                                   String secondSign) {
    //以分隔符划分生成二维数组
    //这个Java好像没有吧,这回没白写

    String firstArray[] = newArray(Str, firstSign);
    String secondArray[] = newArray(firstArray[0], secondSign);
    String tmpArray[][] = new String[firstArray.length][secondArray.length]; //确定数组大小

    for (int I = 0; I < firstArray.length; I++) {
      secondArray = newArray(firstArray[I], secondSign);
      for (int J = 0; J < secondArray.length; J++) {
        tmpArray[I][J] = secondArray[J]; //数组元素赋值
      }
    }

    return tmpArray;
  }

  static String[] newArrayLength(String original[], int length) {
    //用于动态改变数组大小
    //如果增加一个功能,用户可以自己添加删除货币单位,就要用到
    String tmpArray[] = new String[length];
    System.arraycopy(original, 0, tmpArray, 0, original.length);
    return tmpArray;
  }

  static byte[] newArrayByte(String string) { //字符串转Byte数组
    byte tmpArray[] = string.getBytes();
    return tmpArray;
  }

}

class MyInput
    extends Canvas { //自定义输入框的类
  /*
   系统自带组件TextField不能很好的处理小数点输入问题
   大多数情况输入小数点需要切换到字符模式下
   这样用户输入带小数点的数值会很不方便
   所有需要自已定义一个这样的输入框类
  */

  public StringBuffer value = new StringBuffer(""); //存放输入的字符
  int maxLength = 10; //最大输入字符数
  int X, Y; //输入框的坐标

  public MyInput(int x, int y) { //构造方法1
    X = x;
    Y = y;
  }

  public MyInput(int x, int y, String str) { //构造方法2
    X = x;
    Y = y;
    input(str); //赋初值
  }

  public void paint(Graphics screen) {
    screen.setColor(255, 255, 255); //设置前景色为白色
    screen.fillRect(X, Y, getWidth() - 38, 12); //用白色填充指定区域
    screen.setColor(0, 0, 0); //恢复前景色为黑色
    screen.drawString(value.toString(), X + 2, Y - 2, 0); //将输入的字符串输出到指定位置
  }

  void input(String str) {
    if (value.length() < maxLength) { //不超过最大字符数
      value.append(str); //添加输入的字符
    }
  }

  protected void keyReleased(int key) {

    switch (key) { //输入按键输入

      case 48:
        input("0");
        break;
      case 49:
        input("1");
        break;
      case 50:
        input("2");
        break;
      case 51:
        input("3");
        break;
      case 52:
        input("4");
        break;
      case 53:
        input("5");
        break;
      case 54:
        input("6");
        break;
      case 55:
        input("7");
        break;
      case 56:
        input("8");
        break;
      case 57:
        input("9");
        break;

      case 35: //处理负号输入
        if (value.toString().indexOf("-") < 0) {
          value.insert(0, "-");
        }
        else {
          value.delete(0, 1);
        }
        break;

      case 42: //处理小数点输入
        if (value.toString().indexOf(".") < 0 && value.length() > 0) {
          if ( (value.toString().indexOf("-") < 0 && value.length() >= 1) ||
              (value.toString().indexOf("-") == 0 && value.length() >= 2)) {
            input(".");
          }
        }
        break;

      case -8: //退格清除
        if (value.length() > 0) {
          value.delete(value.length() - 1, value.length());
        }
        break;

    }
    repaint();
  }

}

class Math {

//+-*/这4个方法让我好是研究了一阵子,但我还是觉得方法笨了点
//这个程序只用到了*/法

public static String Add(String X, String Y) {

  //浮点数加法运算
  //处理步骤:
  //	1.将浮点数的整数部分和小数部分分离出来
  //	2.让小数位同位
  //	3.整数部分运算
  //	4.小数部分运算
  //	5.处理小数位进位
  //	6.返回运算结果。

  long Xi, Xf; //X的整数部分Xi,X的小数部分Xf
  long Yi, Yf; //X的整数部分Yi,X的小数部分Yf
  long Ri, Rf; //Ri存放整数部分的运算结果,Rf存放小数部分的运算结果
  int Xp, Yp; //Xp,Yp用于处理小数位长度
  String a, b; //两个临时变量,用于处理小数位运算后进位,a为运算后的进位部分,b为运算后的小数部分

  String tmp; //临时变量

  Xi = Long.parseLong(getInt(X)); //X的整数部分
  Xf = Long.parseLong(getFloat(X)); //X的小数部分
  Xp = getFloat(X).length(); //X小数部分的位数

  Yi = Long.parseLong(getInt(Y)); //Y的整数部分
  Yf = Long.parseLong(getFloat(Y)); //Y的小数部分
  Yp = getFloat(Y).length(); //Y小数部分的位数

  //处理同位运算
  tmp = "1";
  if (Xp > Yp) { //例:X=10.232 Y=12.8

    for (int I = 0; I < (Xp - Yp); I++) {
      tmp += "0";
      //生成进位值 如上例 X有3位小数,Y有1位小数,3-1=2 循环2次生成进位值"1"+"0"+"0" ="100"
    }

    Yf = Yf * Long.parseLong(tmp); //如上例 Y的小数8*进位值100=800 这样小数位的运算就变成了232和800
    Yp = Xp; //同步小数位
  }

  if (Xp < Yp) { //例:X=10.2 Y=12.83

    for (int I = 0; I < (Yp - Xp); I++) {
      tmp += "0";
      //生成进位值 如上例 X有1位小数,Y有2位小数,2-1=1 循环1次生成进位值"1"+"0" ="10"
    }

    Xf = Xf * Long.parseLong(tmp); //如上例 X的小数2*进位值10=20 这样小数位的运算就变成了20和83
    Xp = Yp; //同步小数位
  }

  Ri = Xi + Yi; //X、Y整数部分相加
  Rf = Xf + Yf; //X、Y小数部分相加

  tmp = String.valueOf(Rf); //获取分开运算后的小数值

  if (tmp.length() < Xp) { //位数不够前面补"0"
    for (int I = tmp.length(); I < Xp; I++) {
      tmp = "0" + tmp;
    }
    return FormatFloat(Ri + "." + tmp, 2); //返回运算结果
  }

  if (tmp.length() > Xp) { //运算后小数位长度大于原长度要处理进位问题

    a = tmp.substring(0, 1); //提取进位数
    b = tmp.substring(1, Xp + 1); //提取小数部分

    Ri += Byte.parseByte(a); //将原X、Y整数部分运算后的结果加上刚提取出来的进位数

    return FormatFloat(Ri + "." + b, 2); //返回运算结果

  }
  else {
    return FormatFloat(Ri + "." + Rf, 2); //直接返回运算结果
  }

}

  public static String Subtract(String X, String Y) {

    //浮点数减法运算
    //处理步骤:
    //	1.将浮点数的整数部分和小数部分分离出来
    //	2.让小数位同位
    //	3.整数部分运算
    //	4.处理小数位借位
    //	5.小数部分运算
    //	6.返回运算结果。

    long Xi, Xf; //X的整数部分Xi,X的小数部分Xf
    long Yi, Yf; //X的整数部分Yi,X的小数部分Yf
    long Ri, Rf; //Ri存放整数部分的运算结果,Rf存放小数部分的运算结果
    int Xp, Yp; //Xp,Yp用于处理小数位长度
    String Sign = ""; //用算负数标志
    String tmp; //用于小数位同位计算

    if (XbigmoreY(X, Y) == 0) { //如果X小于Y则对它们进行数值互换
      tmp = X;
      X = Y;
      Y = tmp;
      Sign = "-"; //并且添加负数标志
    }

    Xi = Long.parseLong(getInt(X)); //提取X的整数部分
    Xf = Long.parseLong(getFloat(X)); //提取X的小数部分
    Xp = getFloat(X).length(); //获取X小数部分的位数

    Yi = Long.parseLong(getInt(Y)); //提取Y的整数部分
    Yf = Long.parseLong(getFloat(Y)); //提取Y的小数部分
    Yp = getFloat(Y).length(); //获取Y小数部分的位数

    //处理同位运算
    tmp = "1";
    if (Xp > Yp) { //例:X=10.232 Y=12.8

      for (int I = 0; I < (Xp - Yp); I++) {
        tmp += "0";
        //生成进位值 如上例 X有3位小数,Y有1位小数,3-1=2 循环2次生成进位值"1"+"0"+"0" ="100"
      }

      Yf = Yf * Long.parseLong(tmp); //如上例 Y的小数8*进位值100=800 这样小数位的运算就变成了232和800
      Yp = Xp; //同步小数位
    }

    if (Xp < Yp) { //例:X=10.2 Y=12.83

      for (int I = 0; I < (Yp - Xp); I++) {
        tmp += "0";
        //生成进位值 如上例 X有1位小数,Y有2位小数,2-1=1 循环1次生成进位值"1"+"0" ="10"
      }

      Xf = Xf * Long.parseLong(tmp); //如上例 X的小数2*进位值10=20 这样小数位的运算就变成了20和83
      Xp = Yp; //同步小数位
    }

    Ri = Xi - Yi; //X、Y整数部分相减

    if (Xf < Yf) { //如果X的小数部分比Y的小数部分小则Xf借位
      tmp = "1";
      for (int I = 1; I < Xp; I++) {
        tmp += "0";
      }
      Xf += Long.parseLong(tmp += "0"); //加上进位值
      Ri -= 1; //整数部分相应减1
    }

    Rf = Xf - Yf; //X、Y小数部分相减

    tmp = String.valueOf(Rf);
    for (int I = tmp.length(); I < Xp; I++) { //如果长度不够在前面补足"0"
      tmp = "0" + tmp;
    }

    return Sign + FormatFloat(Ri + "." + tmp, 2); //返回运算结果

  }

  public static String Multiplication(String X, String Y) {

    //浮点数乘法运算
    //处理步骤:
    // 1.获取小数点位数
    // 2.将浮点数进位成整数
    // 3.进位后的整数运算
    // 4.处理小数位数
    // 5.返回运算结果

    int Xp, Yp; //Xp,Yp用于处理小数位长度
    String tmp, a, b; //临时存贮用变量

    a = getFloat(X); //X的小数部分
    b = getFloat(Y); //Y的小数部分

    if (Long.parseLong(a) == 0) {
      a = "";
    }
    if (Long.parseLong(b) == 0) {
      b = "";

    }
    Xp = a.length(); //获取X小数部分的位数
    Yp = b.length(); //获取Y小数部分的位数

    X = getInt(X) + a; //进位成整数
    Y = getInt(Y) + b; //进位成整数

    tmp = String.valueOf( (Long.parseLong(X) * Long.parseLong(Y))); //进位后的运算结果

    for (int I = tmp.length(); I < (Xp + Yp); I++) { //如果长度不够在前面补足"0"
      tmp = "0" + tmp;
    }

    a = tmp.substring(0, tmp.length() - (Xp + Yp)); //结果整数部分
    b = tmp.substring(tmp.length() - (Xp + Yp), tmp.length()); //结果小数部分

    if (a.length() == 0) {
      a = "0"; //整数部分为空等于0

    }
    return FormatFloat(a + "." + b, 2); //返回运算结果

  }

  public static String Division(String X, String Y) {

    //浮点数除法运算
    //处理步骤:
    // 1.获取小数点位数
    // 2.将浮点数进位成整数
    // 3.直除取得商值(整数部分)
    // 4.反复进行商、余运算直到除尽或达到最大精确位(小数部分)
    // 5.返回运算结果

    long Xf, Yf; //Xi存放X的小数部分,Xf存放Y的小数部分
    long Xt, Yt; //临时绝对值后的X和Y
    long Quotient, Remainder, Result; //Quotient商、Remainder余、结果Result
    int Xp, Yp; //Xp,Yp用于处理小数位长度
    String tmp, a, b; //临时存贮用变量

    a = getFloat(X); //X的小数部分
    b = getFloat(Y); //Y的小数部分

    if (Long.parseLong(a) == 0) {
      a = "";
    }
    if (Long.parseLong(b) == 0) {
      b = "";

    }
    Xp = a.length(); //获取X小数部分的位数
    Yp = b.length(); //获取Y小数部分的位数

    X = getInt(X) + a; //进位成整数
    Y = getInt(Y) + b; //进位成整数

    //处理同位运算
    tmp = "1";
    if (Xp > Yp) { //例:X=10.232 Y=12.8

      for (int I = 0; I < (Xp - Yp); I++) {
        tmp += "0";
        //生成进位值 如上例 X有3位小数,Y有1位小数,3-1=2 循环2次生成进位值"1"+"0"+"0" ="100"
      }

      Y = "" + Long.parseLong(Y) * Long.parseLong(tmp); //如上例 Y的小数8*进位值100=800 运算就变成了10232和12800
      Yp = Xp; //同步小数位

    }

    if (Xp < Yp) { //例:X=10.2 Y=12.83

      for (int I = 0; I < (Yp - Xp); I++) {
        tmp += "0";
        //生成进位值 如上例 X有1位小数,Y有2位小数,2-1=1 循环1次生成进位值"1"+"0" ="10"
      }

      X = "" + Long.parseLong(X) * Long.parseLong(tmp); //如上例 X的小数2*进位值10=20 这样运算就变成了1020和1283
      Xp = Yp; //同步小数位
    }

    Xt = Long.parseLong(X); //临时将X移到Xt上
    Yt = Long.parseLong(Y); //临时将Y移到Yt上
    if (Xt < 0) {
      Xt *= -1; //保证Xt为正数
    }
    if (Yt < 0) {
      Yt *= -1; //保证Yt为正数

    }
    tmp = "";
    Remainder = Xt;

    for (int I = 0; I < 16; I++) { //反复进行商、余运算直到除尽或达到最大精确位
      Quotient = Remainder / Yt; //求商
      Remainder = Remainder - (Quotient * Yt); //求余
      if (Remainder == 0) {
        break; //如果余等于0表示除尽则跳出运算
      }
      Remainder *= 10; //进位
      Result = Remainder / Yt; //单次运算结果
      tmp += Result; //累加结果
    }

    if (tmp == "") {
      tmp = "0";

    }
    return FormatFloat(Long.parseLong(X) / Long.parseLong(Y) + "." + tmp, 2); //返回运算结果

  }

  static String getInt(String I) { //提取浮点数整数部分

    int point; //point变量存贮小数点在浮点数中的位置
    point = I.indexOf("."); //捕捉小数点位置

    if (point == 0) {
      return "0"; //"."在第1位直接返回0
    }

    if (point < 0) { //(找不到"."point值为-1)
      return I; //如果没有小数点则直接返回整数
    }
    else {
      return I.substring(0, point); //找到就返回小数点前段部分
    }

  }

  static String getFloat(String I) { //提取浮点数小数部分

    int point; //point变量存贮小数点在浮点数中的位置
    point = I.indexOf("."); //捕捉小数点位置

    if (point < 0 || point == (I.length() - 1)) {
      return "0"; //找不到"."或"."在最后1位直接返回0
    }
    else {
      point += 1; //在"."位置上向后移一位是为了方便将小数部分提取出来
      return I.substring(point, I.length()); //找到就返回小数点后段部分
    }

  }

  static int XbigmoreY(String X, String Y) { //浮点数比较X是否大于Y

    long Xi, Xf; //X的整数部分Xi,X的小数部分Xf
    long Yi, Yf; //Yi存放Y的整数部分,Yf存放Y的小数部分
    int Xp, Yp; //Xp、Yp用于处理小数位长度
    String tmp; //临时变量

    Xi = Long.parseLong(getInt(X)); //提取X的整数部分
    Xf = Long.parseLong(getFloat(X)); //提取X的小数部分
    Xp = getFloat(X).length(); //获取X小数部分的位数

    Yi = Long.parseLong(getInt(Y)); //提取Y的整数部分
    Yf = Long.parseLong(getFloat(Y)); //提取Y的小数部分
    Yp = getFloat(Y).length(); //获取Y小数部分的位数

    //处理同位运算
    tmp = "1";
    if (Xp > Yp) { //例:X=10.232 Y=12.8

      for (int I = 0; I < (Xp - Yp); I++) {
        tmp += "0";
        //生成进位值 如上例 X有3位小数,Y有1位小数,3-1=2 循环2次生成进位值"1"+"0"+"0" ="100"
      }

      Yf = Yf * Long.parseLong(tmp); //如上例 Y的小数8*进位值100=800 这样小数位的运算就变成了232和800
      Yp = Xp; //同步小数位
    }

    if (Xp < Yp) { //例:X=10.2 Y=12.83

      for (int I = 0; I < (Yp - Xp); I++) {
        tmp += "0";
        //生成进位值 如上例 X有1位小数,Y有2位小数,2-1=1 循环1次生成进位值"1"+"0" ="10"
      }

      Xf = Xf * Long.parseLong(tmp); //如上例 X的小数2*进位值10=20 这样小数位的运算就变成了20和83
      Xp = Yp; //同步小数位
    }

    if ( (Xi == Yi) && (Xf == Yf)) {
      return 2; //如果X=Y返回2
    }

    if ( (Xi > Yi) || ( (Xi == Yi) && (Xf > Yf))) {
      return 1; //X大Y返回1
    }
    else {
      return 0; //否则返回0
    }
  }

  static String FormatFloat(String X, int length) { //用来处运算结果小数部分多余的0

    String Xi, Xf, tmp; //整数部分Xi,小数部分Xf,临时变量tmp

    Xi = getInt(X); //X的整数部分
    Xf = getFloat(X); //X的小数部分

    if (Xf.length() > length) {
      Xf = Xf.substring(0, length);
    }
    int Xl = Xf.length(); //小数部分长度

    for (int I = 1; I < Xl; I++) {
      tmp = Xf.substring(Xf.length() - 1, Xf.length()); //提取最尾数

      if (Byte.parseByte(tmp) == 0) {
        Xf = Xf.substring(0, Xf.length() - 1); //如果最尾数是0就剔除
      }
      else {
        break; //否则跳出
      }
    }

    if (Long.parseLong(Xf) == 0) {
      tmp = ""; //如果X的小数部分等于0就剔除小数点
    }
    else {
      tmp = "." + Xf; //否则保持原样
    }

    return Xi + tmp; //返回处理结果
  }

}