笔记6-《程序员的数学》按位计数法与指数法则  

目录
  1. 第一章 0 的故事–按位计数法
  2. 什么算按位计数法
  3. N 进制通式
  4. 不使用按位计数法的罗马数字
  5. 指数法则

第一章 0 的故事–按位计数法

  • 按位计数法:8 进制、16 进制、N 进制通式

  • 罗马数字:不使用按位计数法

  • 指数法则

什么算按位计数法

  • 10 进制、2 进制、8 进制、16 进制都叫按位计数法,编程里常用后两种

  • 16 进制用 A ~ F 表示 10 以上的数字,也常用小写

    进制数字种类N⁰N¹N²N³
    20、11248
    80 ~ 71864512
    100 ~ 91101001000
    160 ~ 9、A ~ F1162564096

N 进制通式

  • N 进制的数字是 0 ~ N-1,共 N 种

  • 4 位数的 N 进制 a₃a₂a₁a₀ = a₃ x N³ + a₂ x N² + a₁ x N¹ + a₀ x N⁰,a₀ 到 a₃ 取值 0 ~ N-1

    #ruby
    # N 进制通式:a3*N**3 + a2*N**2 + a1*N**1 + a0*N**0
    def value(digits, base)
    digits.reverse.each_with_index.sum { |d, i| d * base**i }
    end

    puts value([2, 5, 0, 3], 10) # 2503
    puts value([1, 1, 0, 0], 2) # 12
  • 同一个 255,二进制 11111111、八进制 377、十六进制 ff

不使用按位计数法的罗马数字

  • 数位没有意义,只表示数字本身;也没有 0

  • 用 I(1)、V(5)、X(10)、L(50)、C(100)、D(500)、M(1000) 记数

  • 课前对话:1、2、3 的罗马计数法是 I、II、III;II + III 整理后写作 V

  • 并排的数字加起来就是所表示的数:III(3)、VI(6)、VIII(8)

  • 数字多了要「整理」:3 + 3 写成 VI,CXXIII(123) + LXXVIII(78) 整理成 CCI(201)

  • 减法规则:IV 表示 5 - 1 = 4,钟表表盘上因历史原因写作 IIII

  • MCMXCVIII = M + CM + XC + V + III = 1000 + (1000-100) + (1000-10) + 5 + 3 = 1998

    #ruby
    # 罗马数字求值:左边的数比右边小就做减法
    ROMAN = { 'I'=>1, 'V'=>5, 'X'=>10, 'L'=>50, 'C'=>100, 'D'=>500, 'M'=>1000 }

    def to_int(s)
    total = 0
    s.each_char.with_index do |ch, i|
    v = ROMAN[ch]
    nxt = i + 1 < s.length ? ROMAN[s[i+1]] : 0
    total += (v < nxt) ? -v : v
    end
    total
    end

    puts to_int('IV') # 4
    puts to_int('CXXIII') + to_int('LXXVIII') # 201
    puts to_int('MCMXCVIII') # 1998

指数法则

  • 「N 个 10 相乘」定义 10³、10²、10¹ 都很顺,套到 10⁰ 上不成立

  • 换一条规则:指数每减 1,数字就变为原来的 10 分之 1

  • 10¹ 的 10 分之 1 是 1,所以 10⁰ = 1;2¹ 的 2 分之 1 是 1,所以 2⁰ = 1

  • 同样的规则套到负指数:10⁻¹ = 1/10,10⁻² = 1/100

  • 指数法则:Na * Nb = N**(a+b)(N ≠ 0)。前几篇笔记写成加号,原文这里是乘法

    指数3210
    10 的幂1000100101
    2 的幂8421
    #ruby
    puts 10**0 # 1
    puts 2**0 # 1
    puts 10**-1 # 1/10
    puts 10**-2 # 1/100
    puts 2**5 * 2**3 # 256
    puts 2**(5 + 3) # 256
123.8k