Problem
Given a (decimal - e.g. 3.72) number that is passed in as a string, return the binary representation that is passed in as a string. If the fractional part of the number can not be represented accurately in binary with at most 32 characters, return ERROR.
Example
For n = "3.72", return "ERROR".
For n = "3.5", return "11.1".
Note
这道位操作的题目,主要分为整数部分和小数部分的转换。细节上还要考虑正负号和整数位的越界情况。首先,我们对字符串n
用.split("\\.")
把小数点前后的部分分离,存入String[] parts
,整数部分为parts[0]
,小数部分为parts[1]
。然后将parts[0]
通过Integer.parstInt()
转化为int first
,然后将first
的正负设置为符号位boolean isNeg
,建立StringBuilder sb
。
下面开始整数部分的转换,首先考虑越界情况:当first
的值为Integer.MIN_VALUE
的时候,二进制表达为32个1,放入sb
即可。否则对first的绝对值进行运算。对first
(的最低位)和整数1做与运算,结果存入sb
,然后右移一位,进行上一位和整数1的与运算,如此直到first
为0,转换完毕。
小数部分相对更麻烦一些。首先,只有parts[]
有两个元素且parts[1]
不为0时,sb
加入小数点'.'
,然后创建double value
,使用Double.parseDouble("0." + parts[1])
将小数部分存入value
,和整数部分的操作基本一致。
然后我们要考虑两个问题,value
是不是能够完全转换为二进制,以及保证能够在小数点后32
位的范围内完成转换?
所以,我们针对这两点,写出返回ERROR的分支语句。首先在循环外部建立一个HashSet store
,循环内会将出现过的value
存入store
。然后在while循环内判断,如果有重复出现的value
,或者sb
中小数部分的长度超过32,就说明该小数无法完全转换。
然后根据新的value
大小进行十进制到二进制转换运算(value * 2(value < 0.5)
或value * 2 - 1(value >= 0.5)
),将结果加入sb
。如果之前的正负号isNeg
为true
,就在sb
左边加上负号'-'
。
最后,返回sb.toString()
。
Solution
import java.math.*;
public class Solution {
public String binaryRepresentation(String n) {
if (n == null || n.length() == 0) {
return n;
}
String[] parts = n.split("\\.");
StringBuilder sb = new StringBuilder();
int first = Integer.parseInt(parts[0]);
boolean isNeg = first < 0;
if (first == Integer.MIN_VALUE) {
for (int i = 0; i < 32; i++) {
sb.append("1");
}
} else {
first = Math.abs(first);
while (first != 0) {
sb.insert(0, first & 1);
first >>= 1;
}
}
if (sb.length() == 0) {
sb.append("0");
}
//now nail the decimal part
if (parts.length == 2 && Long.parseLong(parts[1]) != 0) {
sb.append(".");
double value = Double.parseDouble("0." + parts[1]);
Set<Double> store = new HashSet<>();
while (value > 0) {
if (sb.substring(sb.indexOf(".")).length() + 1 > 32 || store.contains(value)) {
return "ERROR";
}
store.add(value);
if (value >= 0.5) {
sb.append("1");
value = value * 2 - 1;
} else {
sb.append("0");
value = value * 2;
}
}
}
if (isNeg == true) {
sb.insert(0, "-");
}
return sb.toString();
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。