2025年8月2日 星期六

舉一反三

舉一反三


曾慶潭 Ching-Tang Tseng
ilikeforth@gmail.com
Hamilton, New Zealand
2 August 2025

這是一句所有中國人都耳熟能詳的四字成語,不只是因為它用字簡單,它還是從兩千多年前就開始被中國人使用於教育及學習環境的鼓勵用語。

論語第七章述而篇中有一條孔子的敘述:子曰:「不憤不啟,不悱不發。舉一隅不以三隅反,則不復也。」

它很能說明這就是舉一反三成語的起源。

有過不少賢明的作者彙整出許多有用的成語出版成書,我們在學生時代就買過這種書。例如:『分類中國成語大辭典』。那個年代,電腦還不普及,更沒有網路可以使用,這本有助於自修、作文、書信、寫作的參考用書,是值得花錢買來終生使用的。我買過,很不幸,買書的時候沒有料到平裝書不耐環境的摧殘,用了五六十年的這本書,再翻幾次,封面、封底都得粉化了,就算這樣,我仍然珍惜。為了遣詞用字時少出差錯,也為了閱讀文章時能夠深刻了解且不搞錯文章的意思,經常查找成語工具用書是必要的。閒暇想看書時,成語辭典後面也附有成語故事,看故事書就是享受,也帶有修身養性的意義。

成語大辭典論述舉一反三的短文故事中,鼓勵大家掌握知識、靈活運用、發展知識。這種信而好古的精神,確實是學習的準繩,也是中國文化歷久不衰的主因,有太多的古聖先賢致力於傳承,我們才享受了文化。

我在學習、研發 Forth 的過程中沿用了同樣的方法鼓勵自己,舉一反三是經常做的事情。當然,舉一後不一定非反出三來不可,能夠反出一來也夠有益了,能反出大於三的結果來則是常有的事情。近幾年,我花了不少時間參與了幾個社群媒體的活動,幾乎天天都發表言論。但說實在的,活動產生的真正樂趣,來自別人有正面意義的網貼,我瀏覽它們的程度幾近於天天學習,看到好的題材,必定情不自禁的想方設法節錄下來,留參的多,轉發再炒作的比較少,就算這樣,我貼文的數量經常是高於常人。

最近有個數學帳號的網頁貼出了這麼一個簡單的訊息,訊息很普通,人人能懂,它卻激起了我寫程式的興趣,我用程式證明它。


ABC Forth 可以把程式寫得很簡單,只這樣做只算是舉一反一,我想反二時,問了自己: 64 位元的整數系統能算到多大的數字才會超出單整數能夠表示的範圍? 我寫了程式,得知只能算到 42 。

我還可以反三,能夠設計雙整數的最大公約數與最小公倍數,這樣就能擴大表現範圍,但我沒有這樣做。我跳過了反三,改搞反四,因為我設計的系統能夠處理無限位數的大數字,為了舉一反三而核對已經完成的系統,確定我並沒有為大數系統添加 BigBCD, BigLCM 兩個指令。所以,反四的取向,轉為設計大數字的最大公約數與最小公倍數。

在大數運算系統中,可用位數是可調變的,卻因此而必須先行宣告來決定可用位數,就是因為這樣,我在設計大數系統時才沒有把 BigBCD, BigLCM 兩個函數固定在系統中。

以下是今天寫出來的程式與執行結果:


 

3 integers i n tlcm

: imain 
basic
10 inputi n
10 let tlcm = 1 
20 for i = 1 to n
30 let tlcm = LCM ( tlcm i )
40 next i
50 print tlcm
60 end ; 

0 BIGVARIABLE A 1000 ALLOT
0 BIGVARIABLE B 1000 ALLOT
0 BIGVARIABLE A1 1000 ALLOT
0 BIGVARIABLE B1 1000 ALLOT
0 BIGVARIABLE C1 1000 ALLOT
0 BIGVARIABLE A2 1000 ALLOT
0 BIGVARIABLE B2 1000 ALLOT
0 BIGVARIABLE C2 1000 ALLOT
0 BIGVARIABLE BGCD 1000 ALLOT
0 BIGVARIABLE BLCM 1000 ALLOT

: InputData 
BASIC
10 LET B{ A = S" 12193263112482853211126352690 " S>BIG }B
20 LET B{ B = S" 440370366363 " S>BIG }B
30 END ;

: GCDLCM 
BASIC
10 LET B{ A1 = A }B
20 LET B{ B1 = B }B
30 IF B{ A1 < B1 }B THEN 50
40 GOTO 60
50 LET B{ C1 = A1 }B :: B{ A1 = B1 }B :: B{ B1 = C1 }B
60 LET B{ C1 = A1 MOD B1 }B :: B{ A1 = B1 }B :: B{ B1 = C1 }B
70 IF B{ C1 <> BIG0 }B THEN -60
80 LET B{ BGCD = A1 }B
90 LET B{ BLCM =  ( A * B / BGCD ) }B
100 END ;

: BMAIN 
BASIC
10 RUN InputData
20 RUN GCDLCM
30 PRINT " Big GCD is : "
40 RUN BGCD BIG.
50 PRINT " Big LCM is : "
60 RUN BLCM BIG.
70 END ;

\s
imain

? 10

                2520  OK
imain 

? 42

  219060189739591200  OK
bmain

Big GCD is : 
9 digits 
370370367 
=========1=========2=========3=========4=========5
12345678901234567890123456789012345678901234567890
=========(c) 2018 Copyright, Bottom Ruler=========

Big LCM is : 
32 digits 
14497789840742112468029233348410 
=========1=========2=========3=========4=========5
12345678901234567890123456789012345678901234567890
=========(c) 2018 Copyright, Bottom Ruler=========
 OK