闲来无事,就找了一道程序设计题来练习:编写一个应用程序,读入一个只包含0和1的整数(即二进制整数),然后打印出对等的十进制整数值。要求用求模和除法运算符。于是,我写了如下两个方法:
- public static long readBinaryNum()
- {
- Scanner scan = new Scanner(System.in);
- String binaryNumStr = "";
- boolean available = false;
- do{
- System.out.print("请输入一个二进制整数:");
- binaryNumStr = scan.nextLine();
- available = Pattern.matches("[0-1]+", binaryNumStr);
- if(!available)
- {
- System.out.println("非二进制数据,此次输入无效!");
- continue;
- }
- if(binaryNumStr.length()>=19)
- {
- System.out.println("数据太大,此次输入无效!");
- available = false;
- continue;
- }
- }while(!available);
- return Long.parseLong(binaryNumStr);
- }
- /**
- * 把二进制数值转换为对应的十进制数值
- * @param binaryNum 需要转换的二进制数值
- * @return 对应的十进制数值
- */
- public static long binaryNum2DecimalNum(long binaryNum)
- {
- System.out.println(binaryNum);
- long decimalNum = 0;
- int position[] = new int[(int)Math.log10(binaryNum)+1];
- position[0] = (int)(binaryNum/Math.pow(10, position.length-1));
- for(int i=1;i<position.length;i++)
- {
- position[i] = (int) (binaryNum % (Math.pow(10, position.length - i))
- / (Math.pow(10, position.length - i - 1)));
- }
- for(int i=0;i<position.length;i++)
- {
- decimalNum += position[position.length-i-1] * Math.pow(2, i);
- System.out.print(position[i] + " ");
- }
- System.out.println();
- return decimalNum;
- }
在测试过程中我发现,如果我输入的数据是11111111111111111(即17个1),则程序转换时就出现问题了,结果是131072(而正确结果应该是131071),于是我又测试。最后发现问题出在求余运算处:
- long n = 11111111111111111L;//17个1
- System.out.println(n % Math.pow(10, 1));
- System.out.println(n % 10.0);
- System.out.println(n % 10);
程序运行,输出结果是:
- 2.0
- 2.0
- 1
看到这,我想到这个应该和数值在计算机内的存储结构或者除法的运算机制有关,但我不太清楚里面具体是怎么回事!于是写下此文以备忘,也希望各位看官积极讨论、指教!