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

2023-03-14 16:52 更新

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


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

Go語言提供了兩種精度的復(fù)數(shù)類型:complex64和complex128,分別對應(yīng)float32和float64兩種浮點(diǎn)數(shù)精度。內(nèi)置的complex函數(shù)用于構(gòu)建復(fù)數(shù),內(nèi)建的real和imag函數(shù)分別返回復(fù)數(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"

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

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

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

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

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

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

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

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


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

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

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

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

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



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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號