十进制转二进制

最近在看Java jdk的源码,源码里会用到许多二进制的运算,因此会使用到十进制转二进制的工具。心血来潮想自己实现一个简单的转换工具,心动不如行动,let'go !

温馨提示:文中的代码实现并未考虑性能以及内存消耗,仅跟着思路随手写下,并伴有少许拼音变量名。

正的十进制转二进制比较简单,首先理清楚手算十进制时的过程(原谅我是个灵魂画手):

 从这个计算过程得出:输入的正数除以2,依次记录余数,最终把余数按照倒序(从下往上)拼接在一起即得到结果,5(十进制)=101(二进制)。代码实现:

import java.util.Stack;

public class CalService {

    private Stack stack = new Stack();

    /**
     * 十进制转二进制
     *
     * @param tenNum 十进制数
     * @return 转换的二进制结果
     */
    public String ten2Two(Integer tenNum) {
        StringBuilder sb = new StringBuilder();
            cal(tenNum);
            //输出栈的所有内容得到结果
            while (!stack.empty()) {
                sb.append(stack.pop().toString());
            }
    }

    private void cal(Integer tenNum) {
        //除2取商
        Integer quotient = tenNum / 2;
        //除2取余,把余数放入栈中
        stack.push(tenNum % 2);
        //如果余数大于1继续计算,否则计算结束
        if (quotient > 1) {
            //递归计算
            cal(quotient);
        } else {
            stack.push(quotient);
            return;
        }
    }
}

PS:由于最后需要把余数按照倒序进行拼接,即先入后出,第一个想到的就是使用栈来存放。

负的十进制转二进制会相对复杂一些,概括起来就是其原码的补码。以 -5 来举例:

第一步:计算该负数绝对值的二进制,也就是其正数的原码:

5的原码      101

第二步:int值最多为32位,最高位用于表示正负,正为0,负为1。因此把101的最高位置1,其余位补0,得到负数的原码

-5的原码    10000000 00000000 00000000 00000101

第三步:计算负数原码的反码。正数的反码与原码相同,负数的反码为原码除符号位(最高位的1)外,其余取反

-5的反码    11111111 11111111 11111111 11111010

第四步:计算负数原码的补码。正数的补码与原码相同,负数的补码为反码加1(这也是为什么我们要先算其反码)。

-5的补码    11111111 11111111 11111111 11111011

最终得到-5(十进制)=11111111 11111111 11111111 11111011(二进制)。

上述过程中,蓝色内容就是需要实现的代码逻辑,代码如下:

import java.util.Stack;

/**
 * 十进制转二进制,正、负数均可
 */
public class CalService {

    private Stack stack = new Stack();

    /**
     * 十进制转二进制
     *
     * @param tenNum 十进制数
     * @return 转换的二进制结果
     */
    public String ten2Two(Integer tenNum) {
        StringBuilder sb = new StringBuilder();
        //正数转二进制
        if (tenNum > 0) {
            cal(tenNum);
            while (!stack.empty()) {
                sb.append(stack.pop().toString());
            }
            return sb.toString();
        } else {//负数转二进制
            //计算该负数绝对值的二进制
            tenNum = -tenNum;
            cal(tenNum);
            //判断需要补0的个数
            int buZeroCount = 31 - stack.size();
            //最高位置1,其余位补0,得到负数的原码
            StringBuilder newSb = new StringBuilder();
            newSb.append("1");
            //int最多32位,空的位置补0,加上最高位为1表示负数,补满32位
            for (int i = 0; i < buZeroCount; i++) {
                newSb.append("0");
            }
            while (!stack.empty()) {
                newSb.append(stack.pop().toString());
            }
            //计算反码,原码除符号位(最高位的1)外,其余取反
            String[] bits = newSb.toString().split("");
            for (int i = 1; i < 32; i++) {
                String bit = bits[i];
                if (bit.equals("0")) bits[i] = "1";
                else bits[i] = "0";
            }
            //反码加1
            for (int i = 31; i > 0; i--) {
                String bit = bits[i];
                if (bit.equals("0")) {
                    bits[i] = "1";
                    break;
                } else {
                    bits[i] = "0";
                }
            }
            StringBuilder resultSb = new StringBuilder();
            //输出结果
            for (int i = 0; i < 32; i++) {
                resultSb.append(bits[i]);
            }
            return resultSb.toString();
        }
    }

    private void cal(Integer tenNum) {
        Integer quotient = tenNum / 2;
        stack.push(tenNum % 2);
        if (quotient > 1) {
            cal(quotient);
        } else {
            stack.push(quotient);
            return;
        }
    }
}

为了方便测试,再写一个main方法作为入口:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class main {
    public static void main(String[] arg) throws IOException {
        System.out.print("请输入要转换为二进制的十进制数:");
        CalService calService = new CalService();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(calService.ten2Two(Integer.valueOf(line)));
            System.out.print("请输入要转换为二进制的十进制数:");
        }
    }
}

输出:

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值