编程需要知道多少数学知识?

标签: 程序员 数学 编程 | 发表时间:2012-07-27 02:34 | 作者:唐小娟
出处:http://blog.jobbole.com

下面是我在reddit的子论坛  r/learnprogramming 看到的几个帖子:

● “ 要成为一个优秀的程序员需要学习多少数学?

● “ 我应该重新学习数学吗?

● “ 这可能是我提问过的最愚蠢的一个问题。成为一个优秀的程序员究竟需要学习多少数学?

数学和编程有一种容易让人误解的联系。许多人认为在开始学习编程之前必须对数学很在行或者数学分数很高。但一个人为了编程的话,需要学习多少数学呢?

 

实际上不需要很多。这篇文章中我会深入探讨编程中所需要的数学知识。你可能已经都知道了。

对于基本的编程,你需要知道下面的:

● 加减乘除 — 实际上,电脑会帮你作加减乘除运算。你仅需要知道什么时候运用它们。

● 模运算 — 模运算是用来计算余数,它的符号通常用%百分号来表示。所以23除以7等于3,余数是2。23 mod 7 = 2。

● 判断是奇数还是偶数的模运算 — 如果你想知道一个数是奇数还是偶数,用它mod 2来作模运算。如果结果是0,它就是偶数。如果结果是1,就是奇数。23 mod 2等于1,所以23是奇数,24 mod 2等于0,24是偶数。

● 对一个数作百分数运算,就是用这个数来乘以一个百分数。譬如你要得到279的54%,就是用0。54*279。这就意味着为什么1.0等于100%,0.0等于0%。

● 知道负数是什么。负数乘以负数等于正数。负数乘以正数等于负数。就这么简单。

● 知道卡迪尔坐标系统。在编程中,(0,0)代表屏幕左上角,Y坐标的正轴往下。

● 知道勾股定律,因为它是用来计算笛卡尔坐标中两点之间的距离的。勾股定律a^2 + b^2 = c^2。(x1, y1)和(x2, y2)两点之间的距离等于( (x1 – x2)^2 + (y1 – y2)^2 )。

● 知道十进制、二进制、十六进制。十进制就是我们通常用的十个数:0-9。通常认为这个十进制系统是人类发明的,因为我们有十个手指。

电脑采用二进制数据,只有两个数字:0和1。这是因为我们用电子元件来构建的电脑,让电脑只识别两种状态更便宜些(一种代表0,另一种代表1)。

数是一样的,但是在不同的进制系统里的表现形式不同,因为不同进制包含的数的个数不同。十六进制比十进制多六个数字,所以我们用A-F表示超过9的数。能够表现这些进制系统的最简单方法就是用一个计数器(odometer)。下面三种不同的计数器显示的是同一个数,但在不同的进制系统中的形式不同:

在新窗口中查看计数器页面

在新窗口中查看计数器页面

你甚至不需要知道 怎么从一个进制系统转换成另一个系统。每种 编程语言都有帮你转换的函数。

(提示一下,十六进制的使用是因为一个十六进制的数可以表示四个二进制的数。因为十六进制中的3和二进制中的0011对应,十六进制的A和二进制的1010对应,所以十六进制中的3A(十进制的58)可以写成二进制的00111010。十六进制在编程中的使用是因为它是对二进制的简化。没人喜欢写出的数全是0和1。)

就是这么多了。除了进制系统以外,你可以已经知道编程所需的数学知识了。虽然普遍认为编程需要学习许多数学,但实际上并不需要那么多。你可能为了编写一个程序,譬如说地震模拟器,而需要学习数学。其实你更需要学习地震的数学,而不是因为要编写地震模拟器而学习数学。

 

某些编程领域中更为高级的数学

有一些领域中需要更多的数学知识(但95%的软件中,你都不需要知道它们。)

● 3D游戏和3D绘图 — 3D通常需要涉及三角函数和线性代数(用矩阵来解决问题的数学)。当然,有许多3D图形库已经实现了这些数学编程,你不需要知道这些数学。

● 2D物理(譬如愤怒的小鸟)和3D物理(譬如许多流行的3D游戏) — 为了写涉及到物理的编程,你需要学习一些物理方程和公式(尤其是力学,如弹力,重力,球滚下斜坡等物理。)然而,已经有一些物理引擎和软件库帮你实现了,所以你也不需要知道游戏(如愤怒的小鸟)中的物理公式。

● 加密学 — 事实上我指的是RSA。你需要知道质数的有关知识,以及如何求最大公约数(其实是个非常简单的算法,还有许多编程语言中都有gcd()函数,帮你求解最大公约数)其他的编码大部分就是将数据按照某种步骤挪动。举个例子,下面的 flash就是AES“Rijndael”编码的步骤。所有的步骤包含用一些数减去另一些数,将行向上移,将列数字打乱,再作简单的加法运算。

如果你要写你自己的加密算法(通常不需要你做,因为已经有许多很好的工具了,并且如果你不是加密学的专家的话,你的程序也许会很容易被破解。)如果你仅仅想加密一些数据的话,已经有许多加密和解密的软件库了。

所以就算是以上的情况,你也不需要真正的知道3D图像,物理或者加密的数学。你只需要学习运用软件库就行了。

 

编程需要学习什么?

你需要学习的是如何建模和设计算法。这意味着,如何将真实世界的运算或者数据处理抽象出来,写出代码,让计算机来帮你运算。例如,在游戏“龙与地下城”(Dungeons and Dragons)中,角色和怪兽都有许多不同的战斗统计值:

● 血点(Hit points)是一个人死前所能经受的伤害值。越高的血点就意味着可以经受更多的伤害。

● 防御等级(armor class)是对你的武器防御能力的量度。防御值越低,武器的防御能力越高。

● THAC0(读作“thay-co”,“To Hit Armor Class 0”),是对一个人进行有效攻击的能力的测量。THAC0值越低,攻击越准。

● 武器的攻击力用类似1d6+2来表示,它表示摇一个六面骰得到的值,然后再加2。2d4就是摇2个4面骰,然后将它们相加。(“龙与地下城”采用的是4,6,8,10,12和20面骰。)

dungeons and dragons

要看攻击者打防御者,让攻击者摇动一个20面骰。如果这个数字大于或等于攻击者的THAC0减去防御者的防御能力,那么这个攻击就成功,防御者将受到伤害。不然,防御者就阻击了这个攻击,并且不费血。

我们假设两个人物,Alice和Bob,她们具有以下值:

● Alice: HP 14, AC 5, THAC0 18, DAMAGE 1d6

● Bob: HP 12, AC 7, THAC0 16, DAMAGE 2d4

所以Alice有更多的血点和防御力(记住,AC越低越好)。但是Bob更可能成功击中对方(记住,THAC0越低越好),并造成更多的伤害。我们说Bob的攻击力更强是因为2d4可以造成2-8点伤害,而Alice的1d6只能造成1-6点伤害。(如果你懂统计学,你可以计算出Bob的期望伤害值是5,比Alice的3。5要高。)

你会打赌Alice或者Bob会赢得比赛对吗?很难讲谁会赢,他们看起来势均力敌。尽管可能你的统计学学得很好,但做这个计算将会十分头疼。编写“龙与地下城”的程序(模拟战斗过程),你甚至不需要知道统计学。仅仅需要运行几百次或者几千次战斗,看看谁赢得更多。

 

下面是用Python写的程序:( 下载代码

import random, copy
NUM_FIGHTS = 1
VERBOSE = True
# Lower thac0 and lower ac values are better. Higher damage & hp values are better.
aliceTemplate = {'name': 'Alice', 'hp': 14, 'ac': 5, 'thac0': 18, 'dmgnum': 1, 'dmgsize':6, 'dmgmod': 0}
bobTemplate   = {'name': 'Bob',   'hp': 12, 'ac': 7, 'thac0': 16, 'dmgnum': 2, 'dmgsize':4, 'dmgmod': 0}
def display(s):
    if VERBOSE:
        print(s)
def attack(attacker, defender):
    if random.randint(1, 20) >= attacker['thac0'] - defender['ac']:
        damage = 0
        for i in range(attacker['dmgnum']):
            damage += random.randint(1, attacker['dmgsize'])
        damage += attacker['dmgmod']
        display('%s (%s hp) hits %s (%s hp) for %s points of damage. %s is reduced to %s hp.' % (attacker['name'], attacker['hp'], defender['name'], defender['hp'], damage, defender['name'], defender['hp'] - damage))
        defender['hp'] -= damage
    else:
        display('%s misses %s.' % (attacker['name'], defender['name']))
aliceWins = 0
bobWins = 0
for i in range(NUM_FIGHTS):
    display('======================')
    display('Start of combat #%s' % (i+1))
    alice = copy.deepcopy(aliceTemplate)
    bob = copy.deepcopy(bobTemplate)
    while True:
        attack(alice, bob)
        if bob['hp'] <= 0:
            break
        attack(bob, alice)
        if alice['hp'] <= 0:
            break
    if alice['hp'] <= 0:
        display('Alice has died.')
        bobWins += 1
    if bob['hp'] <= 0:
        display('Bob has died.')
        aliceWins += 1
print()
print('Alice won %s (%s%%) fights. Bob won %s (%s%%) fights.' % (aliceWins, round(aliceWins / NUM_FIGHTS * 100, 2), bobWins, round(bobWins / NUM_FIGHTS * 100, 2)))

当运行这个程序时,你会看到:

Start of combat #1
Alice misses Bob.
Bob (12 hp) hits Alice (14 hp) for 6 points of damage. Alice is reduced to 8 hp.
Alice misses Bob.
Bob misses Alice.
Alice misses Bob.
Bob misses Alice.
Alice misses Bob.
Bob misses Alice.
Alice (8 hp) hits Bob (12 hp) for 5 points of damage. Bob is reduced to 7 hp.
Bob misses Alice.
Alice misses Bob.
Bob misses Alice.
Alice misses Bob.
Bob (7 hp) hits Alice (8 hp) for 2 points of damage. Alice is reduced to 6 hp.
Alice (6 hp) hits Bob (7 hp) for 6 points of damage. Bob is reduced to 1 hp.
Bob misses Alice.
Alice (6 hp) hits Bob (1 hp) for 1 points of damage. Bob is reduced to 0 hp.
Bob has died.
Alice won 1 (100.0%) fights. Bob won 0 (0.0%) fights.

但是可能Alice正好在某一次战斗中很幸运。让我们关掉输出再重新运行程序(在屏幕输出比运行程序更耗时间),当战斗次数达到30,000次时(将NUM_FIGHTS改成30000,VERBOSE变量变成False):

Alice 赢得12909 (43.03%)次战斗. Bob赢得17091 (56.97%)战斗。

所以我们看到使用上面的数值,Bob稍稍占先。电脑进行了30,000次战斗模拟。如果我们用笔和纸还有骰来进行30000次战斗模拟的话,可能需要几个月来算出结果,而我的笔记本仅用了8秒。

那么如果Alice的血点从14增加到20呢。谁会赢呢?

Alice赢得19438 (64.79%)次战斗. Bob赢得10562 (35.21%)次战斗.

我们看到给Alice增加6点血点,结果倒过来了,Alice占先了。那么如果Alice的血点只是增加到16呢?

Alice赢得15176 (50.59%)次战斗啊. Bob赢得14824 (49.41%)次战斗.

所以仅仅增加2个血点,就已经足够扳回Bob更强攻击力的胜算。

来看这个程序,它只用了加减乘除来计算一个百分比。甚至在更复杂的程序中,需要表示magic spells,治愈部位,多次攻击,在战斗中切换武器等不同效果时,我们也不需要知道更多的数学了。

当然,去学更多的数学吧。可以让你成为更出色的 程序员。但是为了学习编程需要多少数学?真的非常少。

更新:我想我应该在基本知识点中增加基本代数,但仅仅需要知道的如 如果X * 3 = 12,知道X等于4。

 

原文: Al Sweigart  编译: 伯乐在线 – 唐小娟

【如需转载,请标注并保留原文链接、译文链接和译者等信息,谢谢合作!】

 

相关文章

相关 [编程 需要 知道] 推荐:

编程需要知道多少数学知识?

- - 博客 - 伯乐在线
下面是我在reddit的子论坛  r/learnprogramming 看到的几个帖子:. ● “ 要成为一个优秀的程序员需要学习多少数学. ● “ 我应该重新学习数学吗. ● “ 这可能是我提问过的最愚蠢的一个问题. 成为一个优秀的程序员究竟需要学习多少数学. 数学和编程有一种容易让人误解的联系.

创业者需要知道的50句话

- Jacqueline - 阮一峰的网络日志
David Cummings 从中总结了50句话,放在一起看,确实很令人收益. 作者:David Cummings. 95%的创业公司不应该融资. 快速增长带来的最大挑战,就是如何让每个员工找到合适自己的位置. 价格战走不远,客户服务才是根本. 成功的最重要因素,就是选对了时机. 为你的团队创造最好的工作环境.

迁移至IPv6所需要知道的十件事

- Tony - cnBeta.COM
互联网在IPv4及其编号系统的助力下,在几十年的时间里提供了亿万个地址. 只要有更多的地址可用,人们就不会考虑IP问题. 但互联网的蓬勃发展最终将所有这些新鲜的数字吸收在内:二月,互联网名称与数字地址分配机构(ICANN)将仅有的几大块未使用的IPv4地址分配给了区域注册商.

男人,你知道女人需要什么样的男人吗?

- renwen - 译言-每日精品译文推荐
来源What women want from all you men. 今天晚上在旧金山市区我有机会和约会专家见面. 当我开始对个人发展和自我提升感兴趣时,就着手研究吸引力. 我认为真正有效指导男人如何吸引女人的建议很少. 阿卡迪是一名律师,同时也是帮助增进男女关系和约会的指导老师. 奈比尔:你可不可以首先介绍一下自己以及你的工作.

你需要知道的 16 个 Linux 服务器监控命令

- - 水煮沉浮
如果你想知道你的服务器正在做干什么,你就需要了解一些基本的命令,一旦你精通了这些命令,那你就是一个 专业的 Linux 系统管理员. 有些 Linux 发行版会提供 GUI 程序来进行系统的监控,例如 SUSE Linux 就有一个非常棒而且专业的工具 YaST,KDE 的 KDE System Guard 同样很出色.

设计 iOS 应用时需要知道的 5 件事

- - 博客 - 伯乐在线
英文原文: 5 Things to Know When Designing for iOS,翻译: oschina. 根据我们制作优秀的 iOS 应用的经验,我们认为设计师应该在心里的牢记适用于 iOS 的 5 件事. 虽然本文关注的重点只在 iOS 应用,但大部分的意见也适用于其他移动平台. 这似乎是显而易见的,设计应用而不是网站实际上需要转变思维方式.

想爬得更高,需要知道的数学体系

- - 博客园_知识库
  在过去的一年中,我一直在数学的海洋中游荡,research进展不多,对于数学世界的阅历算是有了一些长进.   作为计算机的学生,我没有任何企图要成为一个数学家. 我学习数学的目的,是要想爬上巨人的肩膀,希望站在更高的高度,能把我自己研究的东西看得更深广一些. 说起来,我在刚来这个学校的时候,并没有预料到我将会有一个深入数学的旅程.

IT从业人员需要知道的安全知识(1)

- - MySQLOPS 数据库与运维自动化技术分享
最近CSDN等网站被脱库的事情,闹得沸沸扬扬. 身为程序员,我觉得软件开发人员自身安全意识的强弱和 安全知识的多寡会直接影响到所开发系统的安全性. 从这个角度来分析,系统做的不安全有三种原因: A. 不知道存在安全隐患 阅读全文——共4085字 你可能感兴趣的文章. 全球企业开发者技术大会主题信息(0).

影响者营销——你需要知道的9件事

- - 人人都是产品经理
在MarketingProfs B2B营销论坛中,这些问题被一一提出,在Lattice Engines的Amanda Maksymiw的带领下,嘉宾Sam Fiorella与Kevin Cain对这些问题进行了深入的探讨. 更多关于影响者营销的文章可浏览,我们的《影响者营销》专栏. 在论坛开始之前,Makysmiw给嘉宾制定了一条残酷的规则(对观众却是最过瘾的):必须回答所有问题.

java日志,需要知道的几件事

- - Java - 编程语言 - ITeye博客
java日志,需要知道的几件事. 如果对于commons-loging 、log4j 、slf4j 、LogBack 等都已经非常清楚了,可以忽略本文. 几次解决日志冲突问题时对这几个概念的简单总结,希望对这块基础没有理解透的同学能有所帮助,当然如果对这块有更深刻理解的同学,也贡献出自己的知识和见解.