分数到小数

338 阅读1分钟

题目

模拟长除法

public String fractionToDecimal(int numerator, int denominator) {
        if (numerator == 0) {
            return "0";
        }

        StringBuilder ans = new StringBuilder();

        // 判断符号
        if((numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0)) {
            ans.append("-");
        }

        // 转换成long计算
        long fenzi = Math.abs(Long.valueOf(numerator));
        long fenmu = Math.abs(Long.valueOf(denominator));

        // 计算整数部分
        long zhengShuShang = fenzi / fenmu;
        long yuShu = fenzi % fenmu;
        ans.append(zhengShuShang);
        if (yuShu == 0) {
            // 只有整数部分
            return ans.toString();
        } else {
            // 有小数
            Map<Long, Integer> recordMap = new HashMap<>();
            List<Long> shangRecord = new ArrayList<>();
            int index = 0;
            while (yuShu != 0) {
                long temp = yuShu * 10;
                if (recordMap.containsKey(yuShu)){
                    int start = recordMap.get(yuShu);
                    // 如果余数出现过 商也会重复 无需继续循环
                    ans.append(".");
                    for (int i = 0; i < shangRecord.size(); i ++) {
                        if (i == start) {
                            ans.append("(");
                        }
                        ans.append(shangRecord.get(i));
                    }
                    ans.append(")");
                    break;
                }
                shangRecord.add(temp / fenmu);
                recordMap.put(yuShu, index);
                yuShu = temp % fenmu;
                index ++;
            }

            if (yuShu == 0) {
                ans.append(".");
                // 能够整除, 不存在循环小数
                for (int i = 0; i < shangRecord.size(); i ++) {
                    ans.append(shangRecord.get(i));
                }
            }

        }
        return ans.toString();
    }

基本思路

  1. 利用长除法进行计算, 即如果给你两个数字, 让你笔算, 你是怎么算得, 这是核心

  2. 如果出现了重复的余数, 那么对应的商也就会重复, 因此需要记录所有出现过的余数, 以及他们分别对应的商的顺序和值

  3. 整数部分和小数部分分开计算, 有循环小数的情况和没有循环小数的情况也要分开计算

  4. 注意java int数字的边界问题, 在使用Math.abs前, 需要将数字转换成long再使用, 不然就会出现Math.abs(-2147483648) = -2147483648的情况