先写结论: 九进制对文明来说其实是非常不错的进制,虽然可能不如八进制、十六进制、十二进制,但和十进制可能半斤八两,如果按照九进制生活,文明的数学发展水平发展速度并不会和十进制有太大的差异,至于奇数和偶数的概念,更是很早能被发现的,不值一提。
不妨我们 身临其境 一下,以下内容均为 九进制文明视角 。
为了描述方便,在这个视角下,不存在「九/9」这个称谓,所有「九」的称谓都被读作「十」,所以这个文明也自称使用「十进制」。而这个世界中的「百」、「千」、「万」即代表了人类十进制下的 81、729、6561……
【再次提示】:请务必忘记人类使用的十进制!
1)算数
1a)乘法口诀
首先是这个文明中里耳熟能详的 「八八乘法口诀表」:
据说小孩子们最喜欢的口诀是「六六四十」,听起来就很顺。
为了提升孩子们的算术水平,学校组织学生们去参加了「四张扑克牌算 26 点」的活动,当然,算多少点还是有点争议,毕竟大家太熟悉 3 的倍数了,有老师建议「算 22 点」是更合适的,这能锻炼孩子们对 2 、5 的倍数的理解。
这个文明有一个著名的小说叫「东游记」,棠僧经历了八八七十一难才取到真经。
1b)数的整除
对于这个文明,3 和 6 是这个世界最耳熟能详的数字,毕竟这些数的倍数末尾都是 3、6、0。
另外比较有名的说法是「卅数」「丗数」「川数」,这个说法比「奇数」、「偶数」更出名。
「卅数」是指除以 3 余数为 1 的数,也即末尾为 1、4、7 的数;「丗数」是指除以 3 余数为 2 的数,也即末尾为 2、5、8 的数;
「川数」是指能被 3 整除 的数,也即末尾为 3、6、0 的数;
早年的数学研究很多就是围绕着「卅数」和「丗数」展开的。
当然,由于这个国家的性别依旧是 2 个,很快也诞生了「奇数」和「偶数」的概念:偶数是 2 的倍数,奇数不是 2 的倍数。
怎么看一个数是奇数还是偶数呢?
先说一个概念叫「奇数因子」:1、3、5、7。
然后对于不小于两位的数,我们就看「奇数因子」有几个,如果有奇数个,那这个数就是奇数,比如 1 2、4 7 、 333 、6 5 6……反之就是偶数,比如 35 、40、 57 6、 7 28 1 ……
小学数学老师会告诉你,有一个巧妙的方法,可以迅速判定一个数是否为 2、4、8 的倍数: 看它们的数字和是否为 2、4、8 的倍数 。在数学比较好的国度中,8 的倍数们:8、17、26、35、44、53、62、71 都是耳熟能详的。
3 的倍数就不讲了。判断一个数是否是 6 的倍数的方法,就是先看末尾是不是 0/3/6,再看看是不是 2 的倍数。
至于一个数是否为 5、11 的倍数,小学奥赛老师会告诉你:看这个数奇数位的和与偶数位的和之差是否为 5、11 的倍数。比如 5478,个位和百位的和 4+8=13;十位和千位的和 5+7=13,所以这个数是 5、11 的倍数。再比如 35634,奇数位之和 3+6+4 =14;偶数位之和 5+3=8,而 14-8=5,因此 35634 是 5 的倍数,但不是 11 的倍数。
至于一个数是否为 7,14,15 的倍数,一般是超纲内容。超微资深一些的老师会告诉你,有一个简便一些的判别方法,注意到 888 是 7,14,15 的倍数(888=8×7×14=4×14×15),可以将一个大数每 3 位一分割,然后求和,如果这个是 7,14 的倍数,原数也是 7,14 的倍数。
举个例子:23456122,我们先算出:23+456+122= 612,612/7=78 是 7 的倍数,因此 23456122 是 7 的倍数。1c)计算机数学
后来诞生了计算机。这个文明对 3 更熟悉,因此一开始计算机是 3 进制的,毕竟 3 进制表示数据是非常高效的。但后来发现,3 状态的元器件造价太贵,2 状态的元器件要便宜得多,挣扎了十几年后,终于还是把计算机换成了二进制的。
程序员们对 2 的幂次非常熟悉:2,4,8,17,35,71,152,314,628,1357……
考虑到 2 的 10 次方是 628,所以每年的 6 月 28 日被认为是「程序员节」。
人们发现 2 的 11 次方是 1357,一个这么偶数的数,居然每一位都是奇数,还是等差数列,太神奇了!
人们还发现 2 的 21 次方为 878162,这个数和 1000000 仅仅差了 1.07%,非常接近。
于是 1MB = 2^21 B = 878162 B
2)数论
2a)素数
这个国家同样对数论感兴趣,他们比较熟悉 100 以下的 24 个素数:
2、3、5、7、12、14、18、21、25;32、34、41、45、47、52、58、65、67;
74、78、81、87。
100 以内最大的素数是 87。
有意思的是:对于大于 3 的素数,卅数和丗数各有 11 个,很均衡。
业余数学家费牛发现:
都是素数。于是他猜想,2^2^n + 1 都是素数。
但后来人们发现,2^2^5 + 1 = 12068657455 = 782 × 13542217,这个数不是素数!
这个世界里还有一个很著名的数论入门题,它常常用来识别一个人有没有数论天赋:
111111……(n个1) 是不是素数?没有数论天赋的人,可能绞劲脑汁很久都想不出来。但是著名天才数学家低斯,10 岁的时候就用巧妙的方法解决了。
要不你也来试试?
提示:分奇数和偶数讨论,在这个世界里 10=3×3。2b)走马灯数
在这个文明里,人们也会研究其他进制,发现在其他进制中,普遍存在「走马灯数」,也就是说,这个数的倍数会是这个数所有数字的重新组合,而且顺序也不变,只是起点和终点变了。
比如:
但唯独 10 进制,似乎没有这样的「走马灯数」。
后来数学家们发现,因为 10=3×3 是平方数,通过原根的相关知识我们可以证明,在平方数进制下,是不存在走马灯数的,真可惜!
2c)黑洞数
在这个文明里,虽然没有人们耳熟能详的「走马灯数」,却有另一个耳熟能详的数,它是 62853。这个数被成为「黑洞数」。
黑洞数又称陷阱数,是类具有奇特转换特性的整数。任何一个数字不全相同整数,经有限「重排求差」操作,总会得某一个或一些数,这些数即为黑洞数。
比如 31467,将其重新排序后最大的数是 76431 ,最小的数是 13467 ,相减以后得到 62853;
然后继续以上操作:86532 - 23568 = 62853
咦,居然没有发生变化?
这就是黑洞数。
事实上,已经证明,1~4 位数都不存在「黑洞数」,只能跌入循环,于是 62853 是最小的黑洞数。而且,并不是所有的 5 位数都能跌入「黑洞数」的(只有 5210 种初始值可能会跌入这个循环,占 5.8%),更大的可能是,跌入一个「大循环」(除了 11111 的倍数外,其余情况均是如此):
74832 -> 63843 -> 52854 -> 60873 -> 83841 -> 74832:因此「黑洞数」 62853 显得弥足珍贵,很多人都把它设置成密码。
( 代码参见附录 )
3)小数
3a)小数的性质
在该文明的「知也」上,数学区会有一个月经问题:0.8888888…… 是否等于 1 ?
有一个高赞回答是:注意到 1/2 = 0.4444444……,因此 1/2 × 2 = 0.888888…… 所以 0.888888…… 等于 1 。
也对,这个文明的小数发展的更早,毕竟 1/2 = 0.444444……,所以人们很早就发现了「循环小数」。
在进行 10 以下的等分时,循环节最多 3 位,也比较容易记忆,数学老师会要求背诵下来。
3b)圆周率
关于「圆周率」,一开始,人们认为圆周率大概比 3.12 稍微大一点。
巍国数学家刘辉在自己的【八章算数】里仔细研究了下,认为圆周率等于 3.1242,这个数大概是能被整除的。
后来锦国的科学家孙退乎利用「割圆术」,发现刘辉的结果不太精确。他算出圆周率在 3.1241881~3.1241882 之间。
并且给出了两个近似值:
人们发现,圆周率小数点后前 7 位的每一位都是 2 的幂次,人们认为这应该不是巧合。因此认为圆周率后的每一位可能都是 2 的幂次。
直到一千年后,数学大发展,计算圆周率的方式也被进一步优化了,人们发现圆周率后第 12 位是 7,推翻了这一猜想。
现在人们知道,圆周率大约是 3.124188124074427883……
3c)其他常数
后来,科学家发明了对数。定义如果以 10 为底的对数为 lg
于是 lg2≈0.275, lg3=1/2≈0.444,lg5≈0.653
后来马顿发明了微积分,但与此同时祛拳尼兹也独立发现了微积分,两个人大吵一架,不欢而散。
不过这不重要,重要的是,大家发现 e ≈ 2.641557364 这个数似乎也是一个超越数。
注:以上只是该文明的内容提纲,后续内容可以参见专栏系列文章:
附录:「黑洞数」计算代码(好久没用 python,复习一下):
# Calulate the Blackhole Number in Base n
# Author: PlusZeng
# Date: created: 2022/12/4, modified: 2022/12/19
import
math
def
list2chr
(
a
,
n
):
tmp
=
''
if
n
<=
10
:
for
i
in
a
:
tmp
+=
str
(
i
)
if
n
>
10
:
for
i
in
a
:
if
i
<
10
:
tmp
+=
str
(
i
)
elif
i
<
36
:
tmp
+=
chr
(
i
+
55
)
elif
i
<
62
:
tmp
+=
chr
(
i
+
61
)
else
:
tmp
+=
'('
+
str
(
i
)
+
')'
return
tmp
def
root_10_to_n
(
x
,
n
,
x_digit
):
result
=
[];
p
=
n
**
(
x_digit
-
1
);
while
(
p
>=
1
):
result
.
append
(
math
.
floor
(
x
/
p
))
x
%=
p
;
p
/=
n
;
return
result
def
minus_hole
(
x
,
root_n
,
x_digit
):
y_min
=
sorted
(
x
);
a_max
=
0
;
a_min
=
0
;
for
i
in
range
(
0
,
x_digit
):
a_min
+=
int
(
y_min
[
i
])
*
root_n
**
(
x_digit
-
i
-
1
)
a_max
+=
int
(
y_min
[
i
])
*
root_n
**
i
return
root_10_to_n
(
a_max
-
a_min
,
root_n
,
x_digit
)
def
cal_hole_in_base_n
(
x_digit
,
n
):
cirDict
=
{};
for
i
in
range
(
n
**
(
x_digit
-
1
),
n
**
x_digit
):
numList
=
[];
numList
.
append
(
root_10_to_n
(
i
,
n
,
x_digit
));
tmp
=
0
;
is_circle
=
0
;
while
(
is_circle
==
0
):
numList
.
append
(
minus_hole
(
numList
[
tmp
],
n
,
x_digit
))
tmp
+=
1
for
j
in
range
(
tmp
-
1
,
-
1
,
-
1
):
if
numList
[
tmp
]
==
numList
[
j
]:
is_circle
=
1
break
cirList
=
list2chr
(
numList
[
j
],
n
)
for
k
in
range
(
j
+
1
,
tmp
):
cirList
+=
'->'
+
list2chr
(
numList
[
k
],
n
)
if
cirDict
.
get
(
cirList
)
is
None
:
cirDict
[
cirList
]
=
[
list2chr
(
numList
[
0
],
n
)]
else
:
cirDict
[
cirList
]
.
append
(
list2chr
(
numList
[
0
],
n
))
for
i
in
cirDict
.
keys
():
print
(
i
+
' : '
+
str
(
len
(
cirDict
[
i
]))
+
';'
)
if
__name__
==
'__main__'
:
print
(
'Input the base: '
)
n
=
int
(
input
())
print
(
'Input the max digits: '
)
x_digit
=
int
(
input
())
for
i
in
range
(
1
,
x_digit
+
1
):
print
(
'
\n
'
+
str
(
i
)
+
' digits'
)
cal_hole_in_base_n
(
i
,
n
)
print
(
'Done!'
)