专栏首页算法猿的成长程序员的数学笔记1--进制转换

程序员的数学笔记1--进制转换

最近在学习极客时间的课程--程序员的数学基础课。

课程地址:https://time.geekbang.org/column/intro/143

这是第一节课程的学习笔记--有关进制的转换。


二进制

什么是二进制

十进制计数是使用 10 作为基数,例如一个数字:2871,它是十进制表示,也就是

二进制则采用 2 作为基数,它的数位

的形式。例如二进制数字110101,它转换为十进制的表示过程如下:

根据这个思路,八进制(以 8 为基数)和十六进制(以 16 为基数)等计数方法其实也是同样的道理,和十进制的转换也是同样的做法。

利用 Python 代码实现二进制和十进制的转换,如下所示:

# 十进制转二进制的方法:除2取余,逆序排列, https://blog.csdn.net/shirley_sweet/article/details/73896279
def change(n):
    result = '0'
    if n == 0:  # 输入为0的情况
        return result
    else:
        result = change(n // 2)  # 调用自身
        return result + str(n % 2)

def decimal_to_binary(decimal_val):
    '''
    十进制转为二进制
    :param decimal_val:
    :return:
    '''
    print('transfer %d to binary' % decimal_val)
    recursion_result = change(decimal_val)
    print('递归实现转换结果:', recursion_result)

def binary_to_decimal_func(val):
    '''
    按照定义来实现,即 2^n 的形式
    :param val: str
    :return:
    '''
    print('original val: ', val)
    numbers = len(val)
    result = 0
    for i in range(numbers):
        result += int(val[i]) * pow(2, numbers - i - 1)
    return result


def binary_to_decimal(val):
    '''
    二进制转十进制
    :param val:
    :return:
    '''
    decimal2 = binary_to_decimal_func(str(val))
    print('第二种转换二进制为十进制:', decimal2)

实际上,Python 有内建函数可以直接实现这几个进制之间的转换,比如binocthex分别表示将十进制数转换为二进制、八进制和十六进制,而将其他进制转换为十进制,则可以用int(val, base)函数,只是需要注意输入值val必须是字符串,然后设置base参数为当前输入值所用的进制,比如二进制自然是设置base=2,代码如下所示:

def binary_to_decimal(val):
    '''
    二进制转十进制
    :param val:
    :return:
    '''
    # 第一种方法,内建函数--int(),输入值必须是字符串形式
    decimal = int(str(val), 2)
    print('二进制数为: 0b%d' % val)
    print('二进制转换为十进制为:', decimal)

def decimal_to_other_build_function(dec):
    '''
    采用内建函数将十进制转换
    参考 http://www.runoob.com/python3/python3-conversion-binary-octal-hexadecimal.html
    :param dec:
    :return:
    '''
    print("十进制数为:", dec)
    print("转换为二进制为:", bin(dec))
    print("转换为八进制为:", oct(dec))
    print("转换为十六进制为:", hex(dec))

计算机为什么使用二进制?

  1. 二进制的数据表达具有抗干扰能力强、可靠性高的优点;
  2. 二进制非常适合逻辑运算;
  3. 组成计算机系统的逻辑电路通常只有两个状态,即开关的接通和断开。

二进制的位操作

移位操作

二进制左移一位,表示将数字翻倍,即乘以 2 ,但左移需要注意数字溢出的问题,需要考虑当前采用的变量类型位数,比如是int16类型,即只有 16 位数,那么就要考虑当前数值的位数是否达到 16 位了;

二进制右移一位,则表示将数字除以 2 ,并使用整数商,注意右移分为算术右移符号右移,这是因为符号位的原因,一般符号位是0,表示该数值为正数;符号位是1,表示该数值是负数。

对于逻辑右移,需要在右移后在左边补上符号位,即正数补 0,负数补 1 ;

对于算术右移,就是保持符号位不动,其余位数右移。

在 Java 语言中,逻辑右移采用>>>表示,算术右移是>>表示,但 Python 并没有>>>运算符实现逻辑右移的操作。

简单的实现左移操作和算术右移操作:

def left_shift(val, n):
    '''
    左移操作
    :param val:
    :param n: 移动的位数
    :return:
    '''

    print('二进制数为: 0b%d' % val)
    val = int(str(val), 2)
    print('十进制数值:', val)
    result = val << n
    print('left shift %d, result=%s' % (n, result))
    result = bin(int(result))
    print('left shift {}, result={}'.format(n, result))

def right_shift(val, n):
    '''
    右移操作
    :param val:
    :param n:
    :return:
    '''
    print('二进制数为: 0b%d' % val)
    val = int(str(val), 2)
    print('十进制数值:', val)
    math_val = val >> n
    print('right shift {}, math_val={}'.format(n, math_val))
    result = bin(int(math_val))
    print('left shift {}, result={}'.format(n, result))

测试代码如下:

binary_val = 100101
# 输出结果是 0b1001010
left_shift(binary_val, 1)
# 输出结果是 0b10010
right_shift(binary_val, 1)
逻辑操作
  • :参与操作的位中只要有一个是 1,最终结果就是 1;
  • :参与操作的位必须都是 1,最终结果才是 1, 否则就是 0;
  • 异或:参与操作的位相同,最终结果就是 0, 否则是 1。

代码实现如下:

def logic_operation(val1, val2):
    '''
    二进制的逻辑运算,与、或、非以及异或操作
    :param val1:
    :param val2:
    :return:
    '''
    print('orginal val:{},{}'.format(val1, val2))
    dec_val1 = int(str(val1), 2)
    dec_val2 = int(str(val2), 2)
    print('decimal val:{},{}'.format(dec_val1, dec_val2))
    and_result = dec_val1 & dec_val2
    or_result = dec_val1 | dec_val2
    not_result1 = ~dec_val1
    not_result2 = ~dec_val2
    different_or_result = dec_val1 ^ dec_val2
    print('and result:', bin(int(and_result)))
    print('or result:', bin(int(or_result)))
    print('not result1:', bin(int(not_result1)))
    print('not result2:', bin(int(not_result2)))
    print('different or result:', bin(int(different_or_result)))

if __name__ == '__main__':
    binary_val = 100101
    binary_val2 = 110100
    logic_operation(binary_val, binary_val2)

测试的两个二进制数值分别是100101110100,输出结果如下,这里非的操作会实现按位取反,对于有符号数,如果是正数就会变为一个负数。

orginal val:100101,110100
decimal val:37,52
and result: 0b100100
or result: 0b110101
not result1: -0b100110
not result2: -0b110101
different or result: 0b10001

上述源代码的地址是:

https://github.com/ccc013/CodesNotes/blob/master/Maths/Binary.py

点击原文可以直接查看源代码。


本文分享自微信公众号 - 算法猿的成长(AI_Developer),作者:四目

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-01-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【吐血整理】那些让你起飞的计算机基础知识:学什么,怎么学?

    我公众号里的文章,写的大部分都是与计算机基础知识相关的,这些基础知识,就像我们的内功,如果在未来想要走的更远,这些内功是必须要修炼的。框架千变万化,而这些通用的...

    材ccc
  • Python基础入门_2基础语法和变量类型

    Python 基础入门系列第二篇,上一篇简单介绍了为什么用 Python,以及安装和配置环境。

    材ccc
  • 数据结构算法入门--一文了解什么是复杂度

    最近会开始更新一个数据结构算法的学习系列,同时不定期更新 leetcode 的刷题。

    材ccc
  • 【技术分享】随机森林分类

    Bagging采用自助采样法(bootstrap sampling)采样数据。给定包含m个样本的数据集,我们先随机取出一个样本放入采样集中,再把该样本放回初始...

    腾讯智能钛AI开发者
  • 求一个数的临近的较大的2的整数次幂

    在改进一下,就判断他是不是2的次方先。如果是的话,可以直接返回。就可以得到这种方法。面试官又说,不能用循环递归,函数库。这下麻烦了。

    forxtz
  • golang 常见变成问题01

    往 chan 中放数据时,如果缓冲区已经满那么将 block 以下方方式可以试探往 chan 放数据

    landv
  • 【技术分享】带权最小二乘

    $$minimize_{x}\frac{1}{2} \sum_{i=1}^n \frac{w_i(a_i^T x -b_i)^2}{\sum_{k=1}^n w...

    腾讯智能钛AI开发者
  • spark过节监控告警系统实现

    马上要过年了,大部分公司这个时候都不会再去谋求开新业务,而大数据工匠们,想要过好年,就要保证过年期间自己对自己的应用了如执掌。一般公司都会有轮值人员,至少要有春...

    Spark学习技巧
  • spark求最受欢迎的老师的问题

    曼路
  • Spark实现排序

    question: 用spark对数据进行排序,首先按照颜值的从高到低进行排序,如果颜值相等,在根据年龄的升序排序

    曼路

扫码关注云+社区

领取腾讯云代金券