第一章 0 的故事–按位计数法
按位计数法:8 进制、16 进制、N 进制通式
罗马数字:不使用按位计数法
指数法则
什么算按位计数法
10 进制、2 进制、8 进制、16 进制都叫按位计数法,编程里常用后两种
16 进制用 A ~ F 表示 10 以上的数字,也常用小写
进制 数字种类 N⁰ N¹ N² N³ 2 0、1 1 2 4 8 8 0 ~ 7 1 8 64 512 10 0 ~ 9 1 10 100 1000 16 0 ~ 9、A ~ F 1 16 256 4096
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)。前几篇笔记写成加号,原文这里是乘法
指数 3 2 1 0 10 的幂 1000 100 10 1 2 的幂 8 4 2 1 #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