题目
模拟长除法
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();
}
基本思路
-
利用长除法进行计算, 即如果给你两个数字, 让你笔算, 你是怎么算得, 这是核心
-
如果出现了重复的余数, 那么对应的商也就会重复, 因此需要记录所有出现过的余数, 以及他们分别对应的商的顺序和值
-
整数部分和小数部分分开计算, 有循环小数的情况和没有循环小数的情况也要分开计算
-
注意java int数字的边界问题, 在使用Math.abs前, 需要将数字转换成long再使用, 不然就会出现Math.abs(-2147483648) = -2147483648的情况