Go 語(yǔ)言 復(fù)數(shù)

2023-03-14 16:52 更新

原文鏈接:https://gopl-zh.github.io/ch3/ch3-03.html


3.3. 復(fù)數(shù)

Go語(yǔ)言提供了兩種精度的復(fù)數(shù)類型:complex64和complex128,分別對(duì)應(yīng)float32和float64兩種浮點(diǎn)數(shù)精度。內(nèi)置的complex函數(shù)用于構(gòu)建復(fù)數(shù),內(nèi)建的real和imag函數(shù)分別返回復(fù)數(shù)的實(shí)部和虛部:

var x complex128 = complex(1, 2) // 1+2i
var y complex128 = complex(3, 4) // 3+4i
fmt.Println(x*y)                 // "(-5+10i)"
fmt.Println(real(x*y))           // "-5"
fmt.Println(imag(x*y))           // "10"

如果一個(gè)浮點(diǎn)數(shù)面值或一個(gè)十進(jìn)制整數(shù)面值后面跟著一個(gè)i,例如3.141592i或2i,它將構(gòu)成一個(gè)復(fù)數(shù)的虛部,復(fù)數(shù)的實(shí)部是0:

fmt.Println(1i * 1i) // "(-1+0i)", i^2 = -1

在常量算術(shù)規(guī)則下,一個(gè)復(fù)數(shù)常量可以加到另一個(gè)普通數(shù)值常量(整數(shù)或浮點(diǎn)數(shù)、實(shí)部或虛部),我們可以用自然的方式書(shū)寫(xiě)復(fù)數(shù),就像1+2i或與之等價(jià)的寫(xiě)法2i+1。上面x和y的聲明語(yǔ)句還可以簡(jiǎn)化:

x := 1 + 2i
y := 3 + 4i

復(fù)數(shù)也可以用==和!=進(jìn)行相等比較。只有兩個(gè)復(fù)數(shù)的實(shí)部和虛部都相等的時(shí)候它們才是相等的(譯注:浮點(diǎn)數(shù)的相等比較是危險(xiǎn)的,需要特別小心處理精度問(wèn)題)。

math/cmplx包提供了復(fù)數(shù)處理的許多函數(shù),例如求復(fù)數(shù)的平方根函數(shù)和求冪函數(shù)。

fmt.Println(cmplx.Sqrt(-1)) // "(0+1i)"

下面的程序使用complex128復(fù)數(shù)算法來(lái)生成一個(gè)Mandelbrot圖像。

gopl.io/ch3/mandelbrot

// Mandelbrot emits a PNG image of the Mandelbrot fractal.
package main

import (
    "image"
    "image/color"
    "image/png"
    "math/cmplx"
    "os"
)


func main() {
    const (
        xmin, ymin, xmax, ymax = -2, -2, +2, +2
        width, height          = 1024, 1024
    )

    img := image.NewRGBA(image.Rect(0, 0, width, height))
    for py := 0; py < height; py++ {
        y := float64(py)/height*(ymax-ymin) + ymin
        for px := 0; px < width; px++ {
            x := float64(px)/width*(xmax-xmin) + xmin
            z := complex(x, y)
            // Image point (px, py) represents complex value z.
            img.Set(px, py, mandelbrot(z))
        }
    }
    png.Encode(os.Stdout, img) // NOTE: ignoring errors
}

func mandelbrot(z complex128) color.Color {
    const iterations = 200
    const contrast = 15

    var v complex128
    for n := uint8(0); n < iterations; n++ {
        v = v*v + z
        if cmplx.Abs(v) > 2 {
            return color.Gray{255 - contrast*n}
        }
    }
    return color.Black
}

用于遍歷1024x1024圖像每個(gè)點(diǎn)的兩個(gè)嵌套的循環(huán)對(duì)應(yīng)-2到+2區(qū)間的復(fù)數(shù)平面。程序反復(fù)測(cè)試每個(gè)點(diǎn)對(duì)應(yīng)復(fù)數(shù)值平方值加一個(gè)增量值對(duì)應(yīng)的點(diǎn)是否超出半徑為2的圓。如果超過(guò)了,通過(guò)根據(jù)預(yù)設(shè)置的逃逸迭代次數(shù)對(duì)應(yīng)的灰度顏色來(lái)代替。如果不是,那么該點(diǎn)屬于Mandelbrot集合,使用黑色顏色標(biāo)記。最終程序?qū)⑸傻腜NG格式分形圖像輸出到標(biāo)準(zhǔn)輸出,如圖3.3所示。


練習(xí) 3.5: 實(shí)現(xiàn)一個(gè)彩色的Mandelbrot圖像,使用image.NewRGBA創(chuàng)建圖像,使用color.RGBA或color.YCbCr生成顏色。

練習(xí) 3.6: 升采樣技術(shù)可以降低每個(gè)像素對(duì)計(jì)算顏色值和平均值的影響。簡(jiǎn)單的方法是將每個(gè)像素分成四個(gè)子像素,實(shí)現(xiàn)它。

練習(xí) 3.7: 另一個(gè)生成分形圖像的方式是使用牛頓法來(lái)求解一個(gè)復(fù)數(shù)方程,例如$z^4-1=0$。每個(gè)起點(diǎn)到四個(gè)根的迭代次數(shù)對(duì)應(yīng)陰影的灰度。方程根對(duì)應(yīng)的點(diǎn)用顏色表示。

練習(xí) 3.8: 通過(guò)提高精度來(lái)生成更多級(jí)別的分形。使用四種不同精度類型的數(shù)字實(shí)現(xiàn)相同的分形:complex64、complex128、big.Float和big.Rat。(后面兩種類型在math/big包聲明。Float是有指定限精度的浮點(diǎn)數(shù);Rat是無(wú)限精度的有理數(shù)。)它們間的性能和內(nèi)存使用對(duì)比如何?當(dāng)渲染圖可見(jiàn)時(shí)縮放的級(jí)別是多少?

練習(xí) 3.9: 編寫(xiě)一個(gè)web服務(wù)器,用于給客戶端生成分形的圖像。運(yùn)行客戶端通過(guò)HTTP參數(shù)指定x、y和zoom參數(shù)。



以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)