Kirjautuminen

Haku

Tehtävät

Koodit: VB6: Ketjumurtoluku

Kirjoittaja: tnb

Kirjoitettu: 26.02.2004 – 26.02.2004

Tagit: matematiikka, koodi näytille, vinkki

Ketjumurtoluku (continued fraction) on menetelmä, jolla voidaan laskea hyvin tarkkoja desimaaliarvoja funktioille kuten sin(), gamma(), beta(), PI joiden arvot ovat periaatteessa päättymättömiä desimaalilukuja. Ohessa esimerkki sin() function laskennasta. VB:ssä funktio voi kutsua itseään, jolloin ketjumurtoluvun laskenta on helppoa. Menetelmää kutsutan myös rekursioksi.

Function sine(ByVal x As Double) As Double
        'sin(x) functio, tarkkuus noin 10^-15
        If x < 0 Then sine = -sine(-x) : Exit Function
        Dim x3 As Double = Math.PI * Math.Floor(x / Math.PI) ' monesko jakso
        Dim x2 As Double = x - x3 'palautettu nollan lähelle
        sine = x2 / (1 + x2 ^ 2 / ketjumurtoluku(x2, 0))
        If Int(x3) Mod 2 = 1 Then sine = -sine 'joka toinen on negatiivinen
    End Function
    Function ketjumurtoluku(ByVal x As Double, ByVal k As Integer)
        'tarvitaan sin() laskussa
        k = k + 2 'syvyyslaskuria kasvatetaan
        If k = 30 Then ketjumurtoluku = 1 : Exit Function 'riitävän syvä, palataan ylemmäs
        Dim k2 As Double = k * (k + 1)
        Dim x2 As Double = x * x
        ketjumurtoluku = (k2 - x2) + (k2 * x2) / ketjumurtoluku(x, k) 'kutsutaan itseä
    End Function

testiohjelma, buttoniin

Dim i As Integer
Dim x As Double
Dim t1, t2 As Date
Dim ts As TimeSpan
t1 = Now()
For i = 1 To 10000
    sine(1)
Next
t2 = Now()
ts = t2.Subtract(t1)'käytetty aika
TextBox1.Text = (sine(1))
TextBox3.Text = (Math.Sin(1)) 'vb:n sisäinen funktio
TextBox2.Text = (ts.TotalMilliseconds)

Kommentit

nomic [27.02.2004 08:47:24]

#

tästähän oli jopa hyötyä :)

hunajavohveli [27.02.2004 11:45:33]

#

Mietin joskus itsekin, miten tällaisen saisi aikaan. Ajattelin, että jos alusta voisi jotenkin poistaa desimaaleja niin, että ne voitaisiin korvata seuraavilla desimaaleilla, ja sitten tallentaa molemmat desimaaliluvut omiin DOUBLE-muuttujiin ja tarpeen tullen yhdistää. En tiedä kyllä, onko tässä lähellekään sama periaate, kun en oikein äkkiseltään koodista näe, mitä tuo tekee.

sooda [27.02.2004 12:49:54]

#

huh, hieano mutten tajua mitään, kiva kun joku osaa :P

setä [27.02.2004 17:53:38]

#

Kiinnostava aihe mutta taitaa olla VB.NETillä.
Testiohjelmassa luvataan tarkkuudeksi 10^-15 mutta sillä tarkkuudellahan sinin saa suoraan ilman rekursioita.
Minulla on ollut ehkä samankaltaisia ajatuksia kuin hunajavohvelilla eli olen pilkkonut pitkät luvut osiin ja saanut näin numeroita niin pitkän rimpsun kuin katsoa sietää eli töllöön mahtuu. Jollei yhteen ruutuun niin sitten vierittämällä. Seinällä on pii 10000 desimaalin tarkkuudella ja ajatuksena oli tarkistaa, onko desimaalit oikein.

tnb [27.02.2004 21:57:03]

#

Tässä myös PI:n laskenta:

Function PII() As Double
    PII = 3 + 1 / ketjumurtoluku2(0)
End Function

Function ketjumurtoluku2(ByVal k As Double) As Double
    ' PII laskentaan
    k = k + 1
    Dim jakajat() = {3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 3}
    If k > 13 Then ketjumurtoluku2 = 0 : Exit Function
    ketjumurtoluku2 = jakajat(k) + 1 / ketjumurtoluku2(k)
End Function

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta