现在的位置: 首页 > 综合 > 正文

Java将变量中的数据用“二进制”格式输出的方法

2013年06月14日 ⁄ 综合 ⁄ 共 1690字 ⁄ 字号 评论关闭

    今天,在编写一段程序时需要将byte类型的数据,用“二进制”形式的字符串输出,冥思苦想也不知道如何入手。忽然灵机一动记得Java中的Integer包装器类有一个toBinaryString(int i)以二进制(基数2)无符号整数形式返回一个整数参数的字符串表示形式的方法。

查找Java源代码文件Integer.java找到方法源码如下:

public static String toBinaryString(int i) {
    
return toUnsignedString(i, 1);
    }
实际上调用的是toUnsignedString(i, 1);方法再继续查找源码如下:

/**
     * Convert the integer to an unsigned number.
     
*/

    
private static String toUnsignedString(int i, int shift) {
    
char[] buf = new char[32];
    
int charPos = 32;
    
int radix = 1 << shift;
    
int mask = radix - 1;
    
do {
        buf[
--charPos] = digits[i & mask];
        i 
>>>= shift;
    }
 while (i != 0);
    
return new String(buf, charPos, (32 - charPos));
    }

其中,方法中需要使用的数组digits[]定义如下:

final static char[] digits = {
    
'0' , '1' , '2' , '3' , '4' , '5' ,
    
'6' , '7' , '8' , '9' , 'a' , 'b' ,
    
'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
    
'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
    
'o' , 'p' , 'q' , 'r' , 's' , 't' ,
    
'u' , 'v' , 'w' , 'x' , 'y' , 'z'
 }
;
好了,源码已经找到了。现在就开始分析Java类库的设计师们是如何实现它的吧。假设我们这样调用toUnsignedString(5, 1);方法。
1) char[] buf = new char[32];//创建一个char型数组长度32(int型数据在java中是32位的)存放计算后数据。
2) int charPos = 32;//计数器
int radix = 1 << shift;//注意这个地方1是个整型值(32位),它被左移了1位右边空出的用0补充,然后再赋值给了radix。下图是左移前与左移后数据1的二进制表式图: 
  4) int mask = radix - 1;
关键算法如下:
5) do {
6)     buf[--charPos] = digits[i & mask];
7)     i >>>= shift;
8) } while (i != 0);
6) buf[--charPos]因为数组下标是从0开始的,所以起始索引为31(对应内存中的第32位)。digits[i & mask]内存表示图如下:

7)i>>>=shift;

8)  } while (i != 0);//i=2 != 0循环继续5-7步,直至i=0结束循环至此程序运行结束。

9return new String(buf, charPos, (32 - charPos));//调用String类的构造函数,创建一个指定字符数组的字符串对像,程序看到这里问题已经得到解决,下面的代码我就不深究了如果大家感兴趣可以去看源代码。

    总结:研究了Java源代码后对toBinaryString(int i)方法有了更深入的了解, Java库设计师们通过空间来换取速度,不过想想这种浪费空间的方法还是值得的。当然解决问题方法不仅仅只有这一种。

【上篇】
【下篇】

抱歉!评论已关闭.