日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

计算器 abacus 技术文档之二----初步设计

發(fā)布時(shí)間:2025/5/22 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计算器 abacus 技术文档之二----初步设计 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

=======================================

計(jì)算器 abacus 的下載地址:http://www.oschina.net/code/snippet_736932_13725

????? 如果你有關(guān)于 abacus 的問題或者建議,請發(fā)郵件至 zhoucosin@163.com。謝謝。

=======================================??

本節(jié)介紹一些問題以及如何設(shè)計(jì)計(jì)算器以解決這些問題。

程序的目標(biāo):

  • 支持四則混合運(yùn)算 ok.
  • 支持?jǐn)?shù)學(xué)函數(shù),如三角函數(shù)、指對函數(shù)、組合數(shù)等 ok.
  • 支持符號(hào)常量,如圓周率、自然對數(shù)的底數(shù)等? ok.
  • 支持變量運(yùn)算(并非符號(hào)計(jì)算) doing...
  • 支持表達(dá)式函數(shù)(即含有變量的表達(dá)式作為函數(shù)) doing...
  • 支持有控制流程的函數(shù) wait for doing.
???? 首先確定程序的使用方式,目前只打算以命令行的方式運(yùn)行程序,暫不考慮界面的問題,程序啟動(dòng)后,用戶逐條輸入表達(dá)式以計(jì)算其值,每計(jì)算完一個(gè)表達(dá)式并顯示之后,程序?qū)⒌却脩糨斎胂乱粋€(gè)表達(dá)式,直到用戶輸入"quit" 退出程序。

????? 表達(dá)式在本質(zhì)上就是一個(gè)由運(yùn)算符、運(yùn)算數(shù)、標(biāo)點(diǎn)符號(hào)這些表達(dá)式元素組成的序列,所以問題的關(guān)鍵在于解釋這些序列的數(shù)學(xué)意義。

????? 首先需要從字符串形式的表達(dá)式中提取各個(gè)表達(dá)式元素(運(yùn)算符、運(yùn)算數(shù)、標(biāo)點(diǎn)符號(hào):主要是括號(hào)和逗號(hào)),并將這些表達(dá)式元素依次保存到一個(gè)線性的數(shù)據(jù)結(jié)構(gòu)中去,這稱為詞法分析。在詞法分析之前,應(yīng)該進(jìn)行一些預(yù)處理,比如檢查括號(hào)是否匹配。而在詞法分析之后也應(yīng)有一些后處理,比如對標(biāo)識(shí)符作進(jìn)一步處理,詞法分析器只能識(shí)別出標(biāo)識(shí)符,它并不知道一個(gè)標(biāo)識(shí)符到底是一個(gè)函數(shù)的名字還是一個(gè)符號(hào)常量,需要做相應(yīng)的更換。

????? 經(jīng)過詞法分析之后,我們就得到了一個(gè)由表達(dá)式元素所組成的序列了,而表達(dá)式元素都是有相應(yīng)的數(shù)學(xué)意義的,比如運(yùn)算符有優(yōu)先級(jí),需要的運(yùn)算數(shù)個(gè)數(shù),以及最重要的計(jì)算函數(shù)指針這些屬性,而運(yùn)算數(shù)最主要的屬性就是它所對應(yīng)的數(shù)值了。比如表達(dá)式 1-2*(sin(pi/3))^2 在經(jīng)過詞法分析以后將被分割成如下的表達(dá)式元素序列:

???????????????????????? ? ? ? ? ? ? ? ?? ? 1? -? 2? *? (? sin? (? pi? /? 3? )? )? ^? 2

???? 其中的各個(gè)部件都已經(jīng)有了數(shù)學(xué)意義(這需要相應(yīng)的表達(dá)式部件類的實(shí)現(xiàn)),比如運(yùn)算符 * 具有屬性: 字符串體:“*”,優(yōu)先級(jí):2, 所需運(yùn)算數(shù)個(gè)數(shù):2, 計(jì)算函數(shù)指針:(一個(gè)完成乘法運(yùn)算的函數(shù))。而最后的運(yùn)算數(shù)2具有屬性:字符串體:“2”,數(shù)值:2.

????? 這里有一個(gè)非常重要的設(shè)計(jì),就是把數(shù)學(xué)函數(shù)當(dāng)成運(yùn)算符處理。這樣做的理由是,函數(shù)運(yùn)算符跟普通的四則混合運(yùn)算符都能對給定的若干個(gè)實(shí)數(shù),計(jì)算出一個(gè)結(jié)果來,這說明它們在本質(zhì)上是一致的,你可以把加法 2+3 寫成函數(shù)調(diào)用的形式 +(2,3),也可以把函數(shù)調(diào)用 pow(2,3) 按照二元運(yùn)算符的慣例放在兩個(gè)運(yùn)算數(shù)之間: 2 pow 3,想必人們對于 2^3 這樣的指數(shù)寫法習(xí)以為常,那么這個(gè) 2 pow 3 不也是一脈相承的么?而對于一元函數(shù)也是一樣,一元運(yùn)算符負(fù)號(hào)放在運(yùn)算符之前,那么 sin(3) 也可以寫成 sin 3 的形式。總之,把函數(shù)運(yùn)算符跟普通運(yùn)算符統(tǒng)一處理,這是 abacus 在設(shè)計(jì)上的一大特色。

????? 接下來就要調(diào)整表達(dá)式的結(jié)構(gòu),傳統(tǒng)的數(shù)學(xué)表達(dá)式其實(shí)是很不規(guī)范的,歷史上加減乘除這些二元運(yùn)算符最早發(fā)明,很自然的就把它們放在兩個(gè)運(yùn)算符之間了,但同樣的形式對于非二元運(yùn)算符就不適用了。又如,作為一元運(yùn)算符的負(fù)號(hào)是放在運(yùn)算數(shù)之前的,而階乘符號(hào)卻是放在運(yùn)算數(shù)之后的,而函數(shù)運(yùn)算符卻采用了另外一種寫法: opt(a1,a2,.....)。由此可見傳統(tǒng)的數(shù)學(xué)表達(dá)式雖然對人來說是易于理解的,但卻不利于計(jì)算機(jī)進(jìn)行處理,在此我們需要用一種統(tǒng)一的觀點(diǎn)來看待所有的運(yùn)算符,即運(yùn)算符的本質(zhì)是一個(gè)映射,能對給定的若個(gè)數(shù)(輸入)產(chǎn)生一個(gè)確定的結(jié)果(輸出),有了這一點(diǎn)認(rèn)識(shí),我們就希望用一種統(tǒng)一的形式來刻畫表達(dá)式。

????? 我們采用“運(yùn)算符前置”的形式來規(guī)范數(shù)學(xué)表達(dá)式的結(jié)構(gòu),它把任何一個(gè)表達(dá)式放在一對小括號(hào)內(nèi)部,而小括號(hào)內(nèi)的第一個(gè)對象就是運(yùn)算符,剩余的對象均是參與運(yùn)算的運(yùn)算數(shù),例如 2+3 的規(guī)范形式為 (+ 2 3),而 sin(pi) 的規(guī)范式為 (sin pi),并且表達(dá)式可以任意嵌套,比如 5*(2-3) 的規(guī)范形式為 (* 5 (- 2 3)),作為一個(gè)更復(fù)雜的例子,一元二次方程x^2-3x+2=0的求根公式(正根)將表示為 (/ (+ (- (-3)) (sqrt (- ((^ (- 3) 2)) (* (* 4 1) 2)))) (* 2 1)) 。雖然這樣的表達(dá)式對于人來講是一種痛苦,但由于其格式的規(guī)范性,計(jì)算機(jī)是樂于處理這樣的結(jié)構(gòu)的。

????? 由傳統(tǒng)形式向規(guī)范式轉(zhuǎn)換的過程我們就稱之為語法分析,如果有語法錯(cuò)誤,在這個(gè)過程中將會(huì)被發(fā)現(xiàn)。在語法分析之前也應(yīng)該會(huì)有一些預(yù)處理,例如在詞法分析階段并不能區(qū)分負(fù)號(hào)與減號(hào),這需要在語法分析之前進(jìn)行一點(diǎn)“有語法傾向”的檢查糾正,然后根據(jù)括號(hào)的層次提升運(yùn)算符的優(yōu)先級(jí)。

???? 表達(dá)式在經(jīng)過語法分析之后,就已經(jīng)被轉(zhuǎn)換為規(guī)范式了,這個(gè)時(shí)候進(jìn)行計(jì)算就相當(dāng)簡單了,只要采用遞歸的方式,在表達(dá)式中查找主運(yùn)算符(即優(yōu)先級(jí)最低的運(yùn)算符),然后檢查剩余的各個(gè)運(yùn)算對象,如果某個(gè)運(yùn)算對象本身也是一個(gè)表達(dá)式,即含有子表達(dá)式,則先計(jì)算子表達(dá)式的值,最后計(jì)算整個(gè)表達(dá)式的值。 1-2*(sin(pi/3))^2 的計(jì)算過程如下:

轉(zhuǎn)換為規(guī)范式:? (- 1 (* 2 (^ (sin (/ pi 3)) 2)))

計(jì)算過程:

????? Step 1:???? (- 1 (* 2 (^ (sin (/ pi 3)) 2)))

????? Step2:???? (- 1 (* 2 (^ (sin 1.047197551) 2)))

????? Step3:???? (- 1 (* 2 (^ 0.8660256282 2)))

????? Step4:???? (- 1 (* 2 0.7500010327))

????? Step5:???? (- 1 1.500002065)

????? Step6:???? -0.500002065

這樣就完成了計(jì)算過程。在此處可以看到這個(gè)“規(guī)范式”帶來的一個(gè)最大的好處:把語法分析跟遞歸計(jì)算分離開來了,如果不轉(zhuǎn)換成這種規(guī)范式而使用傳統(tǒng)的數(shù)學(xué)表達(dá)式,那么由于表達(dá)式的各種形式(分一元普通運(yùn)算符,二元普通運(yùn)算符,函數(shù)運(yùn)算符.....),就只能在語法分析的過程中根據(jù)相應(yīng)的運(yùn)算符選擇合適的形式來進(jìn)行計(jì)算了。而現(xiàn)在引入了這種規(guī)范式,在計(jì)算過程中根本不用去關(guān)心這個(gè)運(yùn)算符是什么類型的運(yùn)算符。這說明,運(yùn)算符前置表達(dá)式的引進(jìn),是 abacus 的另一個(gè)非常好的設(shè)計(jì)。

????? 至此大體設(shè)計(jì)基本上就完成了。這里有一個(gè)用腦圖描述的計(jì)算器 abacus 的實(shí)現(xiàn),一看就懂的:

http://www.mindomo.com/mindmap/abacus-5b6804e0f3fa466f96bc198c9b5d63d3

zhcosin

2012-10-29

?????

???

轉(zhuǎn)載于:https://my.oschina.net/zhcosin/blog/86083

總結(jié)

以上是生活随笔為你收集整理的计算器 abacus 技术文档之二----初步设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。