进制转换

十进制是我们常常使用的。但是,在计算机中,通用进制是2进制,所以本次写进制转换。在java基础(一)最后一段也用java的类快速转换,今天就简单的实现。

代码略长,简单讲一下,如果是整数,对2取余,最把每次得到的余数倒着写一遍。如果有小数,整数同上,但小数部分乘2,积满1写1并-1,不满写0继续乘。

注意:
如果是负整数,我们要先算原码再求反码最后补码才是答案。
而小数,要进过偏移,组合才是答案。

以下代码注意:浮点数可能和java类写的答案有误差…..不知道怎么解决…. :P

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
import java.util.Scanner;						//如果要使用其他包的类或类库,一定要导入相应的包,否则运行时虚拟局不知道在哪

/** //文档注释,说明类的使用,其方法、字段的说明等等
* 测试十进制的任意数字,转换成二进制、十六进制的方式
* @author KEKEXI
*
*/
public class BinaryConversion { //类名:进制转换
public static void main(String[] args) {
System.out.print("请输入十进制的数:");

Scanner sc = new Scanner(System.in); //定义一个输入的引用 sc
String num = sc.next(); //输入一个浮点型sc.next(),并赋值给num
ChangeNum cn = new ChangeNum(num);
cn.getNumbers(); //把字符串转换成数字,分为整数部分和浮点数部分

System.out.print("输出转换成的二进制:");
if(cn.judgeNum()) //判断num是整数呢,还是浮点数
{
Binary br = new Binary(cn.getIntPart()); //输出二进制和十六进制
br.pinrtNum();
System.out.println("JAVA类的整数二进制:"+Integer.toBinaryString(Integer.parseInt(num))); //比较输出是否和java写的一样

System.out.print("\n输出转换成的十六进制:");
Hexadecimal hc = new Hexadecimal(br.getA());
hc.printHX();
System.out.println("JAVA类的整数十六进制:"+Integer.toHexString(Integer.parseInt(num)));
}
else
{
BinaryDouble bd = new BinaryDouble(cn.getIntPart(), cn.getDouPart());
bd.pinrtNum();
System.out.println("JAVA类的浮点型二进制:"+Integer.toBinaryString(Float.floatToIntBits(Float.parseFloat(num))));

System.out.print("\n输出转换成的十六进制:");
Hexadecimal hc = new Hexadecimal(bd.getA());
hc.printHX();
System.out.println("JAVA类的浮点型十六进制:"+Integer.toHexString(Float.floatToIntBits(Float.parseFloat(num))));
}

}
}

//获取整型和浮点型
class ChangeNum
{
private String num; //private私有属性,提升代码安全性
private int intPart;
private int douPart;

public ChangeNum(String num) //构造方法,获取num
{
this.num = num;
}
public ChangeNum() {} //默认构造方法,在这不需要

public boolean judgeNum() //判断是否整数的方法
{
int k = 0; //定义k,找到'.'的位置,看看有没有"假浮点数",如12.0000,有就化为整数型
boolean flag = false; //判断是否为"假浮点数"
for(int i=0; i<this.num.length(); i++)
{
if(this.num.charAt(i) == '.')
{
k = i;
flag = true;
break;
}
}

int sum = 0; //定义sum,计算小数点后相加的和是否为0,为0说明是假浮点数
if(flag)
{
for(int i=k+1; i<num.length(); i++)
{
sum += num.charAt(i)-'0'; //字符的'0'是48,所以要减去'0'或48才是0
}
}
if(sum == 0) return true;
return false; //为浮点型,返回false
}

public void getNumbers() //浮点数分割,获取整数和浮点数部分
{
if(judgeNum())
{
this.intPart = (int)Double.parseDouble(num); //可能为"假浮点数",先转为double,在转为int
}
else
{
String[] str = this.num.split("\\."); //字符串切割,.为特殊字符,要用\\表示才是普通.
//只要整数部分和浮点数部分,字符就2个
this.intPart = Integer.parseInt(str[0]); //this,指当前类,给当前类的intPart变量赋值
this.douPart = Integer.parseInt(str[1]);
}
}

public int getIntPart() //变量为私有,要设置和获取该变量,有set和get方法,
{ //设置只能我设置,你只能获取,封装性
return intPart;
}

public int getDouPart()
{
return douPart;
}
}

//整型
class Binary
{

private int[] a = new int[32]; //定义a数组,装二进制数,可以为32,也可以为64,都行
private int i = a.length-1; //i为0还是数组长度在输出上有关系
//为0要把数组逆输出,因为我们最先计算的数放到了前面
//比如2,先得a[0]=0, a[1]=1, 答案应该为10,逆输出
//而i=数组长度,a[1]=1,a[0]=0,顺输出
private int intPart; //整数部分就算一个整数,定义该变量就行

Binary(int intPart)
{
this.intPart = intPart;
intNum(this.intPart, a);
}

public Binary() {} //因为有继承关系,要创建默认构造方法

public void intNum(int intPart, int[] a/*, int i*/) //计算二进制的值
{

if(intPart < 0) //如果整数是负的,变为正,一切都以正数处理
{
intPart = -intPart;
a[0] = 1; //符号位变为1,1为负数,0为正数
}
while(intPart != 0)
{
a[i--] = intPart%2; //变为啥,就取啥余,其他进制类同,所以很简单
//位移符,>>右移为除,<<左移为乘
// >>1右移一位为除以2的一次方(2^1)
intPart >>= 1; // >>2右移两位为除以2的2次方(2^2)
}
}

public void complementCode(int[] a) //求补码,正数原码 = 反码 = 补码,所以不用求
{
if(a[0] == 1) //先判断符号位
{
for(int i=1; i<a.length; i++) //先求反码,除符号位,1变0,0变1
{
//if(a[i] == 1) a[i] = 0;
//else a[i] = 1;

//a[i] = a[i]==0 ? 1:0;

a[i] = (a[i]+1)%2;
}

a[a.length-1] += 1; //补码 = 反码+1

for(int i=a.length-1; i>0; i--) //如果有进位,进位变0,前一位加1
{
if(a[i] == 2)
{
a[i] = 0;
a[i-1] += 1;
}
}
}
}

public void pinrtNum()
{
complementCode(a); //调用补码方法

for(int j=0; j<a.length; j++) //打印输出,没4位空一格,好看
{
if(j%4 == 0 && j != 0) System.out.print(' ');
System.out.print(a[j]);
}
System.out.println();
}

public int[] getA()
{
return a;
}
}


//浮点型
class BinaryDouble extends Binary //继承父类
{

private int[] a = new int[32]; //由于父类私有,在重新定义,也可以把父类的修饰符改改
private int i = 0;

private int intPart;
private int douPart;

public BinaryDouble(){}
public BinaryDouble(int intPart,int douPart)
{
this.intPart = intPart;
this.douPart = douPart;
DouNum(intPart, douPart);
}


public void DouNum(int intPart, int douPart)
{
if(intPart < 0) //判断是否为负数
{
a[0] = 1; //获取符号位
intPart = -intPart;
}

//求整数部分
int[] numInt = new int[a.length-1]; //a[0]为符号位,所以结果只能比数组a少1
int intI = numInt.length-1; //还是倒着求二进制

int intPartT = intPart; //intPart要用两次,所以这里临时变量求解

while(intPartT != 0) //本来要用父类的intNum()方法,但无奈,不可以址传递,intI的值还是31
{
numInt[intI] = intPartT%2;
intI--;
intPartT >>= 1;
}


int e = 127+numInt.length-intI-2; //length-1-intI-1求移动小数位,在加127的偏移位

int[] E = new int[a.length-1];
int intE = E.length-1; //也是倒着求二进制

while(e != 0)
{
E[intE] = e%2;
intE--;
e >>= 1;
}

for(int j=intE+1; j<E.length; j++) //一开始赋了符号位,现在先赋E
{
a[++i] = E[j];
}

for(int j = intI+2; j<numInt.length; j++) //在赋整数部分
{
a[++i] = numInt[j];
}


int[] numDou = new int[a.length-1]; //求浮点型部分
int intD = 0; //浮点部分不用倒过来,直接从0开始计算二进制每一位

int t = douPart;
int z = 1; //因为是变为整数,相当于算1.0
while(t != 0)
{
t /= 10;
z *= 10;
}
while(douPart!=0 && intD<numDou.length) //浮点计算,每次*2,大于"1.0",numDou[intD] = 1
{
douPart <<= 1;
numDou[intD++] = douPart>=z ? douPart/z : 0;

if(douPart>=z)douPart -= z;
}

for(int j = 0; j<intD && i<31; j++)
{
a[++i] = numDou[j];
}

}
public void pinrtNum() //重新父类,因为我们不需要算补码
{
for(int j=0; j<a.length; j++)
{
if(j%4 == 0 && j != 0) System.out.print(' ');
System.out.print(a[j]);
}
System.out.println();
}


public int[] getA()
{
return a;
}
}

class Hexadecimal
{
private int[] a = new int [32];
private int[] ans = new int[8];

public Hexadecimal(int[] a)
{
this.a = a;
}
public void aglormHX() //求16进制
{
int k = 0;
int j = 3; //每4位为一组,[0,3]四位,把j=3改为2,就是求八进制
for(int i=0; i<a.length; i++)
{
ans[k] += a[i]<<j; //因为数组a得到的答案为顺序,第一位为2^3,第二位为2^2...2……0

if(j==0) //求完每组,进行下一组
{
k++;
j = 3;
}
else j--;

}
}

public void printHX()
{
aglormHX();
for(int i=0; i<ans.length; i++)
{
switch(ans[i]) //特殊处理[10,15]的数
{
case 10:
System.out.print('A');
break;
case 11:
System.out.print('B');
break;
case 12:
System.out.print('C');
break;
case 13:
System.out.print('D');
break;
case 14:
System.out.print('E');
break;
case 15:
System.out.print('F');
break;
default :
System.out.print(ans[i]);
break;
}
}
System.out.println("H"); //"H"表明它是十六进制
}
}
谢谢您对我的支持
0%