03.02 計算機函數和數學函數有哪些區別和關係?


計算機函數和數學函數都是函數。如果抽象地來說函數的意思就是一個輸入產生一個輸出,那麼這個輸出就是輸入的函數。輸入和輸出之間的這種關係叫做函數映射。

上圖:函數的基本定義示意


不管是計算機函數,還是數學函數,它們都符合函數的這個抽象定義。

函數的要素

  • 輸入

  • 輸出

  • 單向有序對應(輸入對應到輸出)

上圖:這是函數,因為不同的輸入值有唯一的輸出值。

上圖:這不是函數,因為相同的輸入值對應了不同的輸出值。


換一種你可能覺得匪夷所思的方式來描述函數,可以這麼來講:

函數實際上是一個兩兩有序配對的集合,一個X值僅對應一個Y值,但一個Y值不一定對應一個X值。這個X與Y值的配對的集合G就是函數的圖,如果用座標系表示就是我們經常看到的那種函數曲線圖。

上圖:一個典型的函數曲線圖。


從形式上講,函數圖和函數是相同的東西,但函數圖隱藏了函數作為某種過程的內涵。因此,在通常的用法中,函數和函數圖是區分開來講的。

y=f(x)這種表示法就代表了x通過一個函數的過程f,映射(或者輸出)y的全部含義。

此外,函數也稱為映射,雖然“映射”和“函數”之間還是有一些差別。



函數的基本定義是數學的函數和計算機函數通用的,否則就不叫函數。下面我們分開看下數學函數和計算機函數的異同。


數學的函數

函數最早就是在數學領域定義的,因此數學的函數的定義基本上與上面講的函數的基本定義類似,但是數學的函數限定函數的輸入和輸出對象必須是數,而不是其它什麼貓貓狗狗。

你不能說我有一個函數:f(x),然後當x=貓,算出來f(x)=狗。

這樣的函數在數學上不成立的,其根本原因在於數學的運算只能適用於數,這裡的x代表的是一個數,只能從數的集合當中選取。

如果我們把上面的例子再複雜一下,例如:

函數f(x)=2x+1;但你要讓我算當x=貓時的函數值,那我最多可以代數推理到這一步:

f(x)=2貓+1,但是2x貓是什麼含義,2貓能跟+1運算嗎?顯然不行,這哪裡哪呀?完全是牛頭不對馬嘴。

所以,數學的函數,限定了函數的取值範圍是“數”!

這和計算機的函數就有了差別。


計算機的函數

計算機也是建立在數學的原理之上,從計算機的本質上講,計算機就可以被視為一種函數——一種物理實現的函數,它有輸入,有輸出。至少從物理原理上講,它是以電脈衝信號作為輸入,並輸出電脈衝信號。而且計算機確保了函數的一個最基本特徵,即有序對應(或者說映射),相同的輸入對應相同的輸出,絕對不能出現相同的輸入居然產生不同的輸出的情況。所以,計算機本身就具備了函數的某些特質。

上圖:計算機的基本功能是不是跟我們前面對函數的基礎定義的圖示有些相似?


拋開計算機的物理硬件屬性(硬件部分)來說,單看計算機的邏輯屬性(即軟件部分),也就是基於計算機的運作方式而保證成立的那套運作機制,恰恰就是數學函數。計算機的軟件部分可以完全被視為純粹的函數,這一點問題都沒有,因為計算機的軟件體系完全符合函數的基本定義。


只不過,計算機軟件設計人員利用計算機高級編程語言的設計思路,將數學函數的原理和描述方式引入到了計算機的設計和計算機的編程開發當中。並且將複雜的概念建立在了數學函數的基礎上,實現了計算機最重要的操作和行為概念(我們用計算機可不是僅僅用來做算數)。這更強調了之前函數的通用定義當中關於函數是一個“過程”的內涵。

計算機的編程語言不是給計算機看的,而是給程序員看的,是方便程序員自己知道自己想讓計算機執行什麼指令。雖然程序員輸入的是一些程序代碼,但實際上這些程序代碼最終會被編譯為數(包括指令和數據等等)。

上圖:程序的流程圖:大量函數相互連接就構成了複雜的邏輯操作體系。


但實際上計算機的操作和行為,最終落到計算機的硬件底層都是建立在數字信號的基礎上的,這種操作和行為實際上就是大量函數的宏觀集合——通過運算實現對現實世界的反映和反饋。


舉幾個典型的此類操作的例子,看看它們是如何由函數構成的:

  • 計算機指令——實際上是一系列的編號以及相關的參數,每一條計算機指令都定義了輸入值x,計算含義f,指令執行後會產生對應的輸出值和相關操作(以數字信號的方式)。

  • 對計算機內存的讀、寫——實際上是輸入一個地址值,輸出該地址固定長度的數據的值。

  • 對特定設備的操作——實際上在一系列的內存地址寫入各種數值,然後以一個數值請求處理器控制特定的設備來讀取這些數據。

  • 顯示屏顯示圖像——是以顯存內的大量數值作為輸入,以屏幕上的矩陣作為輸出(矩陣也是數的一種形式,至少矩陣可以等效於一個數的有序集合)。

上圖:內存的尋址就是一種典型的數值控制的操作,一串10的組合決定了應該從內存當中的哪一塊提取數據。所以像內存這個設備輸入數值,即可獲取另一串輸出的數值。內存也是一個函數。


上面是從計算機的底層機制來說的,也就是說計算機的底層完全是基於函數的,所謂的計算和操作一切都是函數。


上圖:高級語言(人可讀的指令)是如何變成CPU可讀的指令,一切都會落到01構成的數值上,作為CPU的輸入得到處理。這些數值不僅提供了x,也提供了f,應該說是高層的f,意思是處理數據的方法。高層的f會被變成底層的f,從而會被CPU執行(實際上CPU只知道少量的固定的底層的f)。


而對於計算機編程語言當中的函數來說,函數就具備了更高層次的含義。諸如一個C語言的函數,或者java語言的函數……

這些函數在另一個層面上體現了一些與數學上函數的不同。由於計算機高級語言品種非常多,我這裡也就不過多展開,只說一點點抽象的共性:

在高級編程語言當中,函數和過程(routine)具有類似的含義或者本質,這是對函數"過程"含義的強化,也就是前面我們提到的那個f()的含義。

我們在類似C語言系的語言當中,函數、過程和方法等概念具有類似的含義。這些概念更突出函數的過程屬性。即在函數的運算之中,會執行一些操作,帶來一些後果,重點在於這些操作和操作的後果,而不在於函數的輸出值。但實質上,這些操作的後果也就是函數的輸出值。


通過函數集合的宏觀化,函數就變成了“宏”(macro)——一種具有動作屬性的整體概念,即操作。讀到這裡,讀者應該可以聯想到為什麼excel裡面的VBA程序會被稱為“宏”。

實際上宏就是一種動作,或者操作的集合,其目的不是給出輸出的數值,而是給出一系列動作。但歸根就底,宏也是建立在堆疊的函數的基礎上的,是一個封裝的整體概念,它不過是強調了函數的過程屬性而已。

上圖:Excel中基於VBA的宏程序示例


小結一下:

計算機由於具備了強大的計算能力,於是可以高效地處理大量的函數,因此在此基礎上,人類使得計算機的軟件體系形成了“操作”的概念,因為我們不僅僅是想要計算機通過複雜的函數計算告訴我們一個最終值,而是需要計算機通過計算出來的大量的值去做一些事情。這是將計算力變成生產力的關鍵。但不管操作也好、宏也好、其微觀都是建立在單個簡單的函數的基礎上的,其原理也是建立在數學函數的概念之上的,輸入-過程-輸出的映射是計算機的基本原理。當硬件確保了這種基本原理的穩態運作,就成了計算機。即便用這樣的定義去衡量中國人發明的算盤也是一樣的道理。



總結

數學上函數的概念是計算機函數概念的微觀原理基礎。計算機發展到高級階段之後,計算機函數的含義更多地強調了函數的過程特性,從而形成了強大的操作能力,雖然這種操作能力最終是由硬件來實現的。但無論怎麼發展,計算機函數的內涵都是符合數學函數的內涵的。


小宇堂


這個我之前恰好寫過一篇文章,討論了這個問題。下面摘錄一部分:


在數學中有各種各樣的數學函數,比如 sin ln 等函數,sin(pi/2)=1,ln1 = 0 等等。

C 語言中的函數

在 C 語言中,我們當然也可以使用這些函數,請看如下代碼:

math.h 中包含各種數學函數的目錄,只要將其用 #include 導入,在 main 中使用 sin,log 函數時,程序才知道從哪裡找這些函數。我們在 codeblocks 中執行它,輸出如下:

在數學中,使用函數時可以省略括號,例如 sin pi/2,而 C 語言中的函數則一定要使用 (),例如 sin(pi/2)。在C語言的術語中,pi/2是參數,sin是函數,使用 sin(pi/2) 就是程序員常說的“函數調用”。

C語言函數的“副作用”

事實上,printf(“…”,…); 也是一種函數調用。但是 printf 感覺不像一個數學函數,為什麼呢?因為像 sin 這種函數,傳遞一個參數給它,它會返回給我們一個計算後的值,我們調用 sin 函數就是為了得到它的返回值。至於 printf 函數,我們並不關心它的返回值,更關心的是它的“副作用”(計算返回值的過程中,往控制檯打印的字符。)。事實上,printf 也有返回值,它返回的是實際打印的字符數。

C 語言函數可以有“副作用”,這是它與數學函數的根本區別。


IT劉小虎


兩種函數都有相似的地方,就是好像一個黑箱,送人一個或幾個參數,黑箱的另一端出來了某種結果。但是,數學函數只有數學結果,計算機語言的函數可能有數學以外的結果,比如某種操作。因為,這種操作也符合黑箱的模型:輸入-輸出。

數學上的函數純粹數學的,它本身就是一個實體。所以,可以對數學函數進行其他加工,比如求導、積分;多函數聯立;函數的函數;函數集合等等。計算機函數,即使只是數學的函數,它也只有數值計算,不能當做實體然後再加工。

如果一開始,計算機函數用了另一個名字,比如暗盒,那麼今天就不會有這樣的疑問了,相反可能會問:計算機暗盒與生活中的暗盒有啥區別?


海螺008


計算機中的函數function,和數學中的函數,既有類似也有區別。

一、映射

數學中的函數,就是從輸入到輸出的映射,比如 y = f(x)。

計算機中的函數,有的時候是映射,比如c語言數學庫裡的各種函數,cos(x),sin(x)等,或者字符串處理的函數,比如計算字符串長度 strlen(s),拼接字符串 strcat(str1, str2),等等,對應輸入,有一個輸出。

二、動作

有的時候,計算機中的函數表示一個action的序列,比如畫一條直線 draw_line(p1, p2),根據輸入執行一系列動作;關閉 shutdown(),沒有輸入,直接執行動作。

而數學中的函數就沒有這樣的功能。


實際上,有的編程語言中,對這兩種情況做了區分,表示映射的叫做 function,表示動作的,叫做 procedure


聊科技愛生活


計算機函數是一個處理機,數學函數是一個映射


分享到:


相關文章: