我的Go+语言初体验——(7)Go+ 分数型有理数数据类型
我的Go+語言初體驗——(7)Go+ 分數型有理數數據類型
“我的Go+語言初體驗” | 征文活動進行中…
更多內容,請參閱: 我的Go+語言初體驗——(7)Go+ 分數型有理數數據類型
Go+ 語言使用后綴 ‘r’ 表示有理數,支持分數型有理數數據類型。分數型有理數的定義、運算比較復雜,本文進行了較為系統的測試。
分數型有理數本質上是分子、分母均為整型有理數的數據結構。對分數型有理數變量賦值,可以分子為整型數而分母為整型有理數,或分子為整型有理數而分母為整型數,或分子和分母都是整型有理數。
分數型有理數變量可以與分數型有理數類型的常數或變量進行加減乘除運算,也可以與整型常數、整型有理數常數進行混合運算,不能與其它類型變量進行混合運算。
由于有理數常量的表示中帶有 “r” 和 “<<” 符號,要特別注意其前后運算符號、常數的結合關系、運算優先次序。推薦使用括號 “()” 將其與前后表達式進行隔離,以減少出錯。
1. 有理數數據類型
有理數是整數和分數的集合,整數可以表示為分母為 1 的分數,因此可以用分數來表示任意的有理數。
Go+ 語言支持有理數(Rational number)數據類型,使用后綴 ‘r’ 表示有理數,支持整型、分數型、浮點型三種有理數數據類型:
**bigint:整型有理數。**支持 64位以上的大整數,例如 “1r<<65” 的值等于 2 的 65 次冪,“1r<<65 - 100” 的值等于 2 的 65 次冪減去 100 的結果。
**bigrat:分數型有理數。**支持分數形式表示的有理數,例如 “4/5r” 的值等于分數 4/5。
bigfloat:浮點型有理數0支持浮點數形式表示的有理數。
分數型有理數本質上是分子、分母均為整型有理數的數據結構。
2. 分數型有理數的變量聲明與賦值
2.1 變量聲明與賦值
Go+ 語言使用 var 關鍵字聲明變量,分數型有理數(bigrat)的變量聲明方法如下:
var varname bigrat // 聲明變量 varname 為 bigrat 類型
Go+ 語言允許對分數型有理數變量只聲明不賦值,但系統并不自動為其設置初始值,如果直接調用將發生錯誤,因此推薦在對分數型有理數變量聲明時賦初始值。
**分數型有理數本質上是分子、分母均為整型有理數的數據結構。**因此,對分數型有理數賦值,可以分子為整型而分母為整型有理數,或分子為整型有理數而分母為整型,或分子和分母都是整型有理數。
【例程 1】變量聲明
import "reflect"var brat1 bigrat = 4/5r var brat2 bigrat = 4r / 5 var brat3 bigrat = (1r << 36) / (3r << 65)var brat4 bigrat // 這句沒有報錯,但不推薦使用println reflect.TypeOf(brat1), ", brat1 =: ", brat1 println reflect.TypeOf(brat2), ", brat2 =: ", brat2 println reflect.TypeOf(brat3), ", brat3 =: ", brat3 println reflect.TypeOf(brat4), ", brat4 =: ", brat4 // brat4 尚未賦初值,這句發生錯誤/* Running results: builtin.Gop_bigrat , brat1 =: 4/5 builtin.Gop_bigrat , brat2 =: 4/5 builtin.Gop_bigrat , brat3 =: 1/1610612736 builtin.Gop_bigrat , brat4 =: %!v(PANIC=String method: runtime error: invalid memory address or nil pointer dereference) */程序說明:
(1)在分數型有理數變量聲明時,可以同時對變量賦值,如 brat1~brat3。
(2)對分數型有理數變量賦值,可以分子為整型而分母為整型有理數(如brat1),或分子為整型有理數而分母為整型(如brat2),或分子和分母都是整型有理數(如brat3)。
(3)對分數型有理數變量賦值,系統自動對分數表達式通分化簡,如 brat3。注意 “(1r << 36) / (3r << 65)” 不能寫成 “1r << 36 / 3r << 65”,后者是非法的。
(4)對分數型有理數變量 brat4 只聲明而沒有賦值,系統并不會對變量 brat2 設置初始值,如果直接使用 brat2 將發生錯誤。
2.2 不指定變量類型
Go+ 語言允許不通過 var 聲明變量,在不指定變量類型而直接對變量進行初始化并賦值,編譯器將自動推導變量類型。
- 如果初始化的數值為整數且沒有后綴 ‘r’,系統將其識別為整型變量 int;
- 如果初始化的數值表達為分數形式且沒有后綴 ‘r’,系統將對其取整后識別為整型變量 int;
- 如果初始化的數值為整數且帶有后綴 ‘r’,系統將其識別為整型有理數變量 bigint;
- 如果初始化的數值表達為分數形式,且帶有后綴 ‘r’,系統都將其識別為分數型有理數變量 bigrat;
- 如果初始化的數值表達為分數形式的表達式,且帶有后綴 ‘r’,系統自動對分數表達式進行運算并化簡。
【例程 2】變量初始化時不指定類型
// Example 2: variable initialization without specified type import "reflect"brat3 := 36 brat4 := 6 / 5 brat5 := 306r brat6 := -4/16r brat7 := -4/1r brat8 := 0/1r brat9 := 1r<<20 + 4/5r brat10 := -(1r<<15 + 4) / (5r<<25 - 15)println reflect.TypeOf(brat3), ", brat3 =: ", brat3 println reflect.TypeOf(brat4), ", brat4 =: ", brat4 println reflect.TypeOf(brat5), ", brat5 =: ", brat5 println reflect.TypeOf(brat6), ", brat6 =: ", brat6 println reflect.TypeOf(brat7), ", brat7 =: ", brat7 println reflect.TypeOf(brat8), ", brat8 =: ", brat8 println reflect.TypeOf(brat9), ", brat9 =: ", brat9 println reflect.TypeOf(brat10), ", brat10 =: ", brat10/* Running results: int , brat3 =: 36 int , brat4 =: 1 builtin.Gop_bigint , brat5 =: 306 builtin.Gop_bigrat , brat6 =: -1/4 builtin.Gop_bigrat , brat7 =: -4/1 builtin.Gop_bigrat , brat8 =: 0/1 builtin.Gop_bigrat , brat9 =: 5242884/5 builtin.Gop_bigrat , brat10 =: -32772/167772145 */程序說明:
(1)賦值的數值不帶后綴 ‘r’,編譯器識別變量為整型變量 int,如 brat3, brat4。
(2)賦值的數值表示為整數形式,帶有后綴 ‘r’,編譯器識別變量為整型有理數變量 bigint,如 brat5。
(3)賦值的數值表示為分數形式,帶有后綴 ‘r’,識別變量為分數型有理數變量 bigrat,如 brat6~brat10。
(4)賦值的數值表示為分數 表達式,編譯器自動對編譯器進行計算、化簡。
2.3 用表達式對變量賦值
Go+ 語言允許在通過 var 聲明變量時對變量賦值,也允許不指定變量類型而直接對變量進行初始化并賦值,這兩種情況下都可以使用表達式對變量賦值。
- 使用表達式對變量賦值,編譯器自動對表達式進行計算;
- 使用表達式對變量賦值,編譯器自動對表達式的計算結果進行通分化簡,使分子分母沒有公約數;
- 使用表達式對變量賦值,允許使用整型常數、整型有理數常數,與分數型有理數常數或變量混合運算表達式。
【例程 3】使用表達式對分數型有理數變量賦值
// Example 3: assigning values to variables using expressions import "reflect"var brat1 bigrat = 4/5r var brat2 bigrat = 0/1r var brat3 bigrat = brat1 - 16/4r var brat4 bigrat = 1080 + 3/6r var brat5 bigrat = 1080r + 3/6r var brat6 bigrat = 1080 + 0/1r var brat7 bigrat = 1r<<36 + 6/10r var brat8 bigrat = (1r<<100 - 1) / (5r<<36 + 1)println reflect.TypeOf(brat1), ", brat1 =: ", brat1 println reflect.TypeOf(brat2), ", brat2 =: ", brat2 println reflect.TypeOf(brat3), ", brat3 =: ", brat3 println reflect.TypeOf(brat4), ", brat4 =: ", brat4 println reflect.TypeOf(brat5), ", brat5 =: ", brat5 println reflect.TypeOf(brat6), ", brat6 =: ", brat6 println reflect.TypeOf(brat7), ", brat7 =: ", brat7 println reflect.TypeOf(brat8), ", brat8 =: ", brat8/* Running results: builtin.Gop_bigrat , brat1 =: 4/5 builtin.Gop_bigrat , brat2 =: 0/1 builtin.Gop_bigrat , brat3 =: -16/5 builtin.Gop_bigrat , brat4 =: 2161/2 builtin.Gop_bigrat , brat5 =: 2161/2 builtin.Gop_bigrat , brat6 =: 1080/1 builtin.Gop_bigrat , brat7 =: 343597383683/5 builtin.Gop_bigrat , brat8 =: 422550200076076467165567735125/114532461227 */程序說明:
(1)可以用表達式對分數型有理數變量進行賦值,表達式可以混合使用帶有后綴 ‘r’ 的整型有理數常數和不帶后綴 ‘r’ 的整型常數。
(2)編譯器自動對表達式進行計算,如 brat3~brat8。
(3)編譯器自動對表達式的計算結果進行通分化簡,使分子分母沒有公約數,如 brat4, brat5, brat7。
(4)使用表達式對分數型有理數變量賦值,允許使用帶有整型常數、整型有理數常數的混合運算表達式,如 brat4~brat6。
(5)使用表達式對分數型有理數變量賦值,允許使用帶有分數型有理數常數或變量的表達式,如 brat3, brat8。
3. 分數型有理數的運算
分數型有理數變量可以與分數型有理數類型的常數或變量進行加減乘除運算,也可以與整型常數、整型有理數常數進行混合運算,不能與其它類型變量進行混合運算。
3.1 分數型有理數運算式接受的數據類型
分數型有理數的運算表達式中,
- 運算式中允許使用整型常數、整型有理數常數;
- 運算式中允許使用分數型有理數常數,允許使用分數型有理數變量;
- 運算式中允許使用 “分數”,不允許使用浮點數常數或變量。
注意:Go+ 語言中并沒有 “分數” 數據類型。雖然 “4/5” 看起來好像是一個分數,實際上這是一個整數表達式:整數 4 除以 整數 5。
【例程 4】分數有理數計算式接受的數據類型
// Example 4: Accepted data type in operation of fractional rational numbersimport "reflect"var brat1 bigrat = 4/5r var brat2 bigrat = (1r<<100 - 1) / 12345 var brat3 bigrat = (1r<<100 - 1) / (5r<<36 + 1) println reflect.TypeOf(brat1), ", brat1 =: ", brat1 println reflect.TypeOf(brat2), ", brat2 =: ", brat2 println reflect.TypeOf(brat3), ", brat3 =: ", brat3brat4 := brat1 + 1024 brat5 := brat1 + 4/5 brat6 := brat1 + 1r<<65 brat7 := brat1 + 306/1025r brat8 := brat1 + brat2println reflect.TypeOf(brat4), ", brat4 =: ", brat4 println reflect.TypeOf(brat5), ", brat5 =: ", brat5 println reflect.TypeOf(brat6), ", brat6 =: ", brat6 println reflect.TypeOf(brat7), ", brat7 =: ", brat7 println reflect.TypeOf(brat8), ", brat8 =: ", brat8/* builtin.Gop_bigrat , brat1 =: 4/5 builtin.Gop_bigrat , brat2 =: 84510040015215293433113547025/823 builtin.Gop_bigrat , brat3 =: 422550200076076467165567735125/114532461227 builtin.Gop_bigrat , brat4 =: 5124/5 builtin.Gop_bigrat , brat5 =: 4/5 builtin.Gop_bigrat , brat6 =: 184467440737095516164/5 builtin.Gop_bigrat , brat7 =: 1126/1025 builtin.Gop_bigrat , brat8 =: 422550200076076467165567738417/4115 */【例程 5】分數有理數運算不接受的數據類型
// Example 5: Unaccepted data type in operation of fractional rational numbersimport "reflect"var xint int = 1024 var ybint bigint = 1r << 65 var brat1 bigrat = 1024 / (5r << 36)brat4 := brat1 + 0.8 // 報錯 //invalid operation: brat1 + 0.8 (mismatched types github.com/goplus/gop/builtin.Gop_bigrat and untyped float)brat5 := xint + 320/7027r // 報錯 //invalid operation: xint + 320/7027r (mismatched types int and github.com/goplus/gop/builtin.Gop_untyped_bigrat)var brat6 bigrat = ybint + 320/7027r // 報錯 //panic: gox.fatalMsg("don't call End(), please use EndInit() instead") [recovered]brat7 := ybint + 320/7027r // 這句沒有報錯,但不推薦使用 println reflect.TypeOf(brat7), ", brat7 =: ", brat7 // 這句報錯 //panic: TODO: can't init bigint from bigrat程序說明:
(1)分數型有理數的運算表達式,不允許使用浮點數常數或變量,如 brat4 的運算式是錯誤的。
(2)分數型有理數的運算表達式,不允許整型變量與分數分數型有理數運算,如 brat5 的運算式是錯誤的。
(3)分數型有理數變量申明時使用表達式賦值,不允許使用整型有理數變量,如 brat6 是錯誤的。
(4)在分數型有理數的運算表達式中,使用整型有理數變量與分數型有理數常數進行運算,雖然沒有直接報錯,但計算結果是不合法的,因此也要避免使用。
說明:關于分數型有理數的數據類型,有些地方容易混淆,下文將進行進一步的分析。
3.2 分數型有理數的四則運算
分數型有理數的基本運算,如加減乘除,其計算方法和規則與通常的四則運算相同,運算結果表示為通分化簡的分數型有理數。
【例程 6】分數型有理數的基本運算
// Example 6: : Basic operations with constants of rational numbers import "reflect"var brat1 bigrat = 4/5r var brat2 bigrat = (1r<<100 - 1) / 12345 var brat3 bigrat = (1r<<100 - 1) / (5r<<36 + 1)println "brat1 + brat2 = ", brat1+brat2 println "brat1 - brat2 = ", brat1-brat2 println "brat1 * brat2 = ", brat1*brat2 println "brat1 / brat2 = ", brat1/brat2println "brat1 + brat2 / brat3 = ", brat1+brat2/brat3 println "(brat1 + brat2) / brat3 = ", (brat1+brat2)/brat3 println "brat1 + (brat2 / brat3) = ", brat1+(brat2/brat3)/* Running results: brat1 + brat2 = 422550200076076467165567738417/4115 brat1 - brat2 = -422550200076076467165567731833/4115 brat1 * brat2 = 67608032012172234746490837620/823 brat1 / brat2 = 3292/422550200076076467165567735125 brat1 + brat2 / brat3 = 114532464519/4115 (brat1 + brat2) / brat3 = 48395714406674320425927525589687130857659/1738794073313054662386311230039375 brat1 + (brat2 / brat3) = 114532464519/4115 */程序說明:
(1)分數型有理數的基本運算,如加減乘除,其計算方法和規則與通常的四則運算相同,運算結果表示為通分化簡的分數型有理數。
(2)分數型有理數的基本運算,按照先乘除、后加減的順序進行運算。
(3)分數型有理數運算式的運算結果,表示為通分化簡的分數型有理數。
3.3 分數型有理數變量與整型變量的混合運算
Go+ 語言中分數型有理數變量可以與整型變量進行混合運算,運算結果為分數有理數;分數型有理數不能與整型有理數進行混合運算。
【例程 7】分數型有理數變量與整型變量的運算
// Example 7: Mixed operation of fractional rational number variable and integer variable var xint int = 1024 var ybint bigint = 1r << 36var brat1 bigrat = 4/5r var brat2 bigrat = (1r<<100 - 1) / 12345 var brat3 bigrat = (1r<<100 - 1) / (5r<<36 + 1)println brat1+xint // brat1 + xint = 5124/5 println brat2-2*xint // brat2 - 2*x = 84510040015215293433111861521/823 println brat1*xint // brat1 * xint = 4096/5 println brat2/xint // brat2 /xint = 84510040015215293433113547025/842752println brat1+ybint // 錯誤:invalid operation println brat2-2*ybint // 錯誤:invalid operation println brat1*ybint // 錯誤:invalid operation println brat2/2*ybint // 錯誤:invalid operation程序說明:
(1)分數型有理數變量可以與整型變量進行混合運算,運算結果為分數有理數。
(2)分數型有理數不能與整型有理數進行混合運算——這一點有些意外,也需要特別注意。
3.4 分數型有理數常量與整型變量的混合運算
分數型有理數常量與整型變量、整型有理數變量進行混合運算,往往容易發生類型錯誤,建議盡量避免。
【例程 8】整型有理數與浮點數的運算
// Example 8: Mixed operation of fractional rational number constant and integer variablevar xint int = 1024 var ybint bigint = 1r << 36 var brat1 bigrat = 4/12345rprintln brat1+xint+320/7027r //3978508/86748315 println xint+320/7027r //錯誤:invalid operation: xint+320/7027rprintln brat1-ybint+320/7027r //錯誤:invalid operation: brat1-ybint println ybint+320/7027r //錯誤:panic: TODO: can't init bigint from bigrat3.5 分數型有理數常量與整型常量的混合運算
分數型有理數常量可以與整型常量、整型有理數常量進行混合運算,運算結果為分數型有理數。
一般來說,分數型有理數常量不能與浮點數常量進行混合運算;特殊情況如果浮點數的值是整數,可以自動轉換為整型,可以運算,但鑒于這種混合運算很容易發生類型錯誤,建議盡量避免。
【例程 9】整型有理數與浮點數的運算
// Example 9: Mixed operation of fractional rational number constant and integer constantprintln 320/7027r+1024 // 7195968/7027 println 320/7027r*1024/5 // 65536/7027 println 320/7027r*1024/5.0 // 65536/7027 //println 320/7027r*1024/5.5 // 錯誤:invalid operation: 320/7027r*1024/5.5println 320/7027r+1024r // 7195968/7027 println 320/7027r*1024r/5 // 65536/7027 println 320/7027r*1024r/5.0 // 65536/7027 //println 320/7027r*1024r/5.5 // 錯誤:invalid operation: 320/7027r*1024r/5.5//println 320/7027r*(1r<<24)/5.0 // 1073741824/7027 //println 320/7027r*(1r<<24)/5.5 // 錯誤:invalid operation: 320/7027r*(1r<<24)/5.5println 320/7027r+1r<<24 // 117893497152/7027 println 320/7027r*(1r<<24) // 5368709120/7027 //println 320/7027r*1r<<24 // 錯誤:invalid operation: 320/7027r*1r<<24println 320/7027r+1r<<24/5 // 117893498432/35135 println 320/7027r+1r<<(24/5) // 112752/7027程序說明:
(1)由于有理數常量的表示中帶有 “r” 和 “<<” 符號,要特別注意其前后運算符號、常數的結合關系、運算優先次序。例如,"320/7027r*(1r<<24)“可以正確運算,而"320/7027r*1r<<24” 發生錯誤。
(2)注意由于運算優先次序的不同,"320/7027r+1r<<24/5"與"320/7027r+1r<<(24/5)"的結果不同。
因此,對于整型有理數常數和分數型有理數常數,推薦使用括號 “()” 將其與前后表達式進行隔離,以減少出錯。
4. 總結
-
Go+ 語言使用后綴 ‘r’ 表示有理數,支持分數型有理數數據類型(Rational number)。
-
Go+ 語言允許在通過 var 聲明變量時對變量賦值,也允許不指定變量類型而直接對變量進行初始化并賦值,這兩種情況下都可以使用表達式對變量賦值。
-
Go+ 語言允許對分數型有理數變量只聲明不賦值,但系統并不自動為其設置初始值,如果直接調用將發生錯誤,因此推薦在對分數型有理數變量聲明時賦初始值。
-
分數型有理數本質上是分子、分母均為整型有理數的數據結構。對分數型有理數變量賦值,可以分子為整型數而分母為整型有理數,或分子為整型有理數而分母為整型數,或分子和分母都是整型有理數。
-
對分數型有理數變量賦值,系統自動對表達式進行運算和通分化簡。
-
分數型有理數變量可以與分數型有理數類型的常數或變量進行加減乘除運算,也可以與整型常數、整型有理數常數進行混合運算,不能與其它類型變量進行混合運算。
-
分數型有理數變量可以與整型變量進行混合運算,運算結果為分數有理數;分數型有理數不能與整型有理數進行混合運算。
-
分數型有理數常量可以與整型常量、整型有理數常量進行混合運算,運算結果為分數型有理數。
-
由于有理數常量的表示中帶有 “r” 和 “<<” 符號,要特別注意其前后運算符號、常數的結合關系、運算優先次序。推薦使用括號 “()” 將其與前后表達式進行隔離,以減少出錯。
5. 附錄:出錯的代碼匯總
以下是本文中出現程序錯誤的代碼,供大家參考。
// 錯誤代碼匯總var brat4 bigrat // 這句沒有報錯,但不推薦使用brat4 := brat1 + 0.8 // 報錯:invalid operation brat5 := xint + 320/7027r // 報錯:invalid operation brat6 := ybint + 320/7027r // 這句沒有報錯,但不推薦使用var brat6 bigrat = ybint + 320/7027r // 報錯:panicprintln brat1+ybint // 錯誤:invalid operation println brat2-2*ybint // 錯誤:invalid operation println brat1*ybint // 錯誤:invalid operation println brat2/2*ybint // 錯誤:invalid operationprintln xint+320/7027r //錯誤:invalid operation: xint+320/7027r println brat1-ybint+320/7027r //錯誤:invalid operation: brat1-ybint println ybint+320/7027r //錯誤:panic: TODO: can't init bigint from bigratprintln 320/7027r*1024/5.5 // 錯誤:invalid operation: 320/7027r*1024/5.5println 320/7027r*1024r/5.0 // 這句沒有報錯,但不推薦使用 println 320/7027r*1024r/5.5 // 錯誤:invalid operation: 320/7027r*1024r/5.5println 320/7027r*(1r<<24)/5.0 // 這句沒有報錯,但不推薦使用 println 320/7027r*(1r<<24)/5.5 // 錯誤:invalid operation: 320/7027r*(1r<<24)/5.5println 320/7027r*(1r<<24) // 正確:5368709120/7027 println 320/7027r*1r<<24 // 錯誤:invalid operation: 320/7027r*1r<<24【本節完】
版權聲明:
原創作品,轉載必須標注原文鏈接:(https://blog.csdn.net/youcans/article/details/121874187)
Copyright 2021 youcans, XUPT
Crated:2021-12-10
歡迎關注『我的Go+語言初體驗』系列,持續更新中…
我的Go+語言初體驗——(1)超詳細安裝教程
我的Go+語言初體驗——(2) IDE 詳細安裝教程
我的Go+語言初體驗——(3)Go+ 數據類型
我的Go+語言初體驗——(4)零基礎學習 Go+ 爬蟲
我的Go+語言初體驗——(5)Go+ 基本語法之 Switch
我的Go+語言初體驗——(6)Go+ 整型有理數數據類型
我的Go+語言初體驗——(7)Go+ 分數型有理數數據類型
“我的Go+語言初體驗” | 征文活動進行中…
總結
以上是生活随笔為你收集整理的我的Go+语言初体验——(7)Go+ 分数型有理数数据类型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux进入字符界面编程,MPlaye
- 下一篇: 微调多层自编码算法