Matriisitulo ja muuta vaikeaa matikkaa.

Oletko tehnyt jotain, mistä muut voisivat hyötyä. Postita vinkit tänne.
JATothrim
Tech Developer
Tech Developer
Posts: 606
Joined: Tue Aug 28, 2007 6:46 pm
Location: Kuopio

Matriisitulo ja muuta vaikeaa matikkaa.

Post by JATothrim »

En jostain syystä millään ilveellä, en sitten millään, tahtonut osata kirjoittaa matriisituloa koodiksi.
Näimpä tein ohjelman joka näyttää idioottivarmasti, kuinka matriisien kertotaulu menee:
Ohjelma tukee tällä hetkellä nm matriseja, mutta osaa asetella tuloksen oikein vain kun n == m? :| Ohjelma näyttää myös tapahtuuko useita samanlaisia kertolaskuja, jotka kannattaa laskea ennalta. Koodin loppuun kukin itse saa tehdä tiedostoon tulostus funktion, joka muotoilee tuloksen miten hyvittaa. Niin.. matriisi on tosiaan Colum-Major muodossa. ;)

Otsikko viittaa siihen, että tänne saa laittaa myös muita vaikeasti hahmotettavia tai monimutkaisia matemaattisia asioita.

Code: Select all

// n-m Matriisitulon (t)ulostaja (C) JATothrim
 
Const Ah = 4	'A matriisin korkeus	(kerrottava matriisi)
Const Bw = 4	'B matriisin leveys		(kertova matriisi)

mwh% = Max(Ah, Bw)
power% = mwh*mwh
cubic% =  power * mwh

SCREEN 70 * mwh, 12 * power + 5 * mwh

Dim hXYZW(24) As String
Dim lXYZW(24) As String
Dim row(cubic+1) As String

Ai% = 0
Bj% = 0
i% = 0
j% = 0
t% = 0

For i = 0 To 23
	hXYZW(i) = Mid("XYZWQRSTUIJKLMNOPEADFGHB", i+1, 1)
	lXYZW(i) = Mid("xyzwqrstuijklmnopeadfghb", i+1, 1)
Next i
i = 0

SetFont LoadFont("Courier New", 16)

// Generoidaan sarakkeiden ja rivien pistetulot, ja näytetään ne "yhdistelmä" matriisissa:
Repeat
	// "CiMj" (Colum-i, Major-j) "tulo notatiossa" C merkki edustaa saraketta A matriisissa.
	// i merkki edustaa C sarakkeen komponenttia A matriisissa.
	// M merkki edustaa riviä B matriisissa ja j rivin komponenttia M rivillä.
	// "C Sarakeen i alkio KERTAA M Rivin j alkio"
	row(t) = hXYZW(Ai)+lXYZW(i)+"*"+hXYZW(Bj)+lXYZW(j)
	
	'Text (t / power) * 70,(t Mod power)*12 + 5 * (t / mwh) - 5 * mwh * (t / power),row(t)
	'DrawScreen OFF
	t + 1
	i + 1
	Bj + 1
	
	If Bj = i And i >= Ah
		j + 1
		i = 0
		Bj = 0
	EndIf
	
	If j >= Bw
		j = 0
		Ai + 1
	EndIf

Until Ai >= Ah

'Cls

// Erotellaan duplikaatti operaatiot ("CiMj" on sama kuin "MjCi")
For i = 0 To (cubic-1)
	inv$ = Right(row(i), 2)+"*"+Left(row(i), 2)
	For j = i+1 To (cubic-1)
		If inv = row(j)			
			row(i) = row(i) + Chr(65+counter Mod 24) + Chr(48 + counter / 24)
			row(j) = Chr(65+counter Mod 24) + Chr(48 + counter / 24)
			counter+1
			Exit
		EndIf
	Next j
Next i


// Tulostettujen lohkojen "CiMj"-tulot siis summataan paikalleen, jolloin saamme valmiin matriisin.

// Tämän voisi laittaa vaikka (t)ulostamaan valmiin lasku funktion.. :D
Repeat
For t = 0 To (cubic-1)
	Text (t / power) * 70,(t Mod power)*12 + 5 * (t / mwh) - 5 * mwh * (t / power),row(t)
Next t
DrawScreen
Wait 1
Forever
-On selkeästi impulsiivinen koodaaja joka...
ohjelmoi C++:lla rekursiivisesti instantioidun templaten, jonka jokainen instantiaatio instantioi sekundäärisen singleton-template-luokan, jonka jokainen instanssi käynistää säikeen tulostakseen 'jea'.
MaGetzUb
Guru
Posts: 1715
Joined: Sun Sep 09, 2007 12:35 pm
Location: Alavus

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by MaGetzUb »

Miten sitten voisi tehdä laskukoneen jossa olisi perus +, -, /, * toiminnot ja algoritmina olisi Käänteinen Puolalainen Notaatio? :)
Solar Eclipse
Meneillä olevat Projektit:
We're in a simulation, and God is trying to debug us.
User avatar
axu
Devoted Member
Posts: 854
Joined: Tue Sep 18, 2007 6:50 pm

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by axu »

MaGetzUb wrote:Miten sitten voisi tehdä laskukoneen jossa olisi perus +, -, /, * toiminnot ja algoritmina olisi Käänteinen Puolalainen Notaatio? :)
Tässäpä on:

Code: Select all

Dim par1, par2, res oper$, calc$

Repeat
    calc = Input("Anna laskutoimitus: ")
    DrawScreen
Until KeyHit(28)

While CountWords(calc) > 1
    par1 = GetWord(calc, 1)
    par2 = GetWord(calc, 2)
    oper = GetWord(calc, 3)
    Select oper
        Case "+"
            res = par1 + par2
        Case "-"
            res = par1 - par2
        Case "*"
            res = par1 * par2
        Case "/"
            res = par1 / par2
    EndSelect
    Print res
    calc = Replace(calc, par1 + " " + par2 + " " + oper, Str(res))
    Print calc
Wend

WaitKey
Virheellisissä laskutoimituksissa tuntuu herkästi heittävän loputtomaan looppiin, mutta tämä olettaakin, että käyttäjä tietää mitä tekee. Vain kokonaisluvuilla toimii! Teen ehkä joskus paremman version, tämä oli viidessä minuutissa kasattu.
Jos tämä viesti on kirjoitettu alle 5 min. sitten, päivitä sivu. Se on saattanut jo muuttua :roll:
Image
Latexi95
Guru
Posts: 1166
Joined: Sat Sep 20, 2008 5:10 pm
Location: Lempäälä

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by Latexi95 »

axu wrote:
MaGetzUb wrote:Miten sitten voisi tehdä laskukoneen jossa olisi perus +, -, /, * toiminnot ja algoritmina olisi Käänteinen Puolalainen Notaatio? :)
Tässäpä on:

Code: Select all

Dim par1, par2, res oper$, calc$

Repeat
    calc = Input("Anna laskutoimitus: ")
    DrawScreen
Until KeyHit(28)

While CountWords(calc) > 1
    par1 = GetWord(calc, 1)
    par2 = GetWord(calc, 2)
    oper = GetWord(calc, 3)
    Select oper
        Case "+"
            res = par1 + par2
        Case "-"
            res = par1 - par2
        Case "*"
            res = par1 * par2
        Case "/"
            res = par1 / par2
    EndSelect
    Print res
    calc = Replace(calc, par1 + " " + par2 + " " + oper, Str(res))
    Print calc
Wend

WaitKey
Virheellisissä laskutoimituksissa tuntuu herkästi heittävän loputtomaan looppiin, mutta tämä olettaakin, että käyttäjä tietää mitä tekee. Vain kokonaisluvuilla toimii! Teen ehkä joskus paremman version, tämä oli viidessä minuutissa kasattu.
Paitsi, että tuossa ei ole käänteistä puolalaista notaatiota. Ei sulkuja yms.
Sitä varten suositttelen tutustumaan tähän.
Koodiapina
Forum Veteran
Posts: 2396
Joined: Tue Aug 28, 2007 4:20 pm

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by Koodiapina »

Latexi95 wrote:Paitsi, että tuossa ei ole käänteistä puolalaista notaatiota. Ei sulkuja yms.
Ei käänteisessä puolalaisessa notaatiossa tarvita sulkuja.
MaGetzUb wrote:Miten sitten voisi tehdä laskukoneen jossa olisi perus +, -, /, * toiminnot ja algoritmina olisi Käänteinen Puolalainen Notaatio? :)
Käänteinen puolalainen notaatio ei ole algoritmi vaan merkintätapa. Nyt jää vähän epäselväksi, mitä todella tahdot. Kenties laskufunktion, jossa infix-syöte muutetaan RPN-lausekkeeksi ennen laskemista?
Last edited by Koodiapina on Tue Feb 15, 2011 3:29 pm, edited 1 time in total.
User avatar
axu
Devoted Member
Posts: 854
Joined: Tue Sep 18, 2007 6:50 pm

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by axu »

Latexi95 wrote:Paitsi, että tuossa ei ole käänteistä puolalaista notaatiota. Ei sulkuja yms.
Sitä varten suositttelen tutustumaan tähän.
Tämähän nimenomaan laskee käänteisen puolalaisen notaation avulla. Ilmeisesti siis ajattelit, että lasku annetaan normaalissa muodossa (esim. (4 + 5) / 10)), joka sitten muutetaan RPN muotoon (4 5 + 10 /) tuolla algoritmilla johon heitit linkkiä, josta se lasketaan? Käänteinen Puolalainen Notaatio.

No tässä on sitten ainakin tuo loppuosa tuosta laskimesta, eli RPN muodosta tulos esille.
EDIT:

Pitäisikö muuten tuon RPN-algoritmin tukea 3:a tai useampia operandeja?

Last edited by axu on Tue Feb 15, 2011 7:31 pm, edited 1 time in total.
Jos tämä viesti on kirjoitettu alle 5 min. sitten, päivitä sivu. Se on saattanut jo muuttua :roll:
Image
Latexi95
Guru
Posts: 1166
Joined: Sat Sep 20, 2008 5:10 pm
Location: Lempäälä

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by Latexi95 »

Anteeksi axu, katselin koodiasi aika hätäisesti... Itse ainakin oletin MaGetzUpin haluavan tehdä laskimen ja oletti se olevan helpointa rpn kautta (mikä taitanee pitää paikkansa) ja halusi vinkkejä toteutuksesta. Linkkasin tuohon sillä veikkasin ongelmien olevan lähinnä rpn:n muodostamisessa ei niinkään laskemisessa.
EDIT:

Muistaakseni juu.

xamuli
Newcomer
Posts: 16
Joined: Thu Oct 07, 2010 4:40 pm

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by xamuli »

Oon lukion ekalla, joten en tiedä miten matriiseja käytetään, mun pitäis saada laskettua kahden janan leikkauspiste ja löysin tämän, voisko joku neuvoa miten tolla sivulla olevat X = ... ja Y = ... hommat lasketaan (ovatko ne edes matriiseja?) ja onko helpompaa keinoa selvittää kahden janan leikkauspiste.

Nämä ovat siis ne mitä en osaa:

X =ImageY =Image
koodaaja
Moderator
Moderator
Posts: 1583
Joined: Mon Aug 27, 2007 11:24 pm
Location: Otaniemi - Mikkeli -pendelöinti

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by koodaaja »

Ehdottomasti helpompia tapoja löytyy :) Voit esimerkiksi ratkaista janoja vastaavien suorien yhtälöt ja kokeilla leikkaavatko suorat semmoisella alueella, jolla molemmat janat ovat voimassa.
SPuntte
Tech Developer
Tech Developer
Posts: 650
Joined: Mon Aug 27, 2007 9:51 pm
Location: Helsinki, Finland
Contact:

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by SPuntte »

xamuli wrote:voisko joku neuvoa miten tolla sivulla olevat X = ... ja Y = ... hommat lasketaan (ovatko ne edes matriiseja?) ja onko helpompaa keinoa selvittää kahden janan leikkauspiste.
Yhtälössä on matriiseja, mutta niiden ympärillä olevat pystyviivat esittävät itseisarvomerkkejä, mikä matriisien tapauksessa tarkoittaa determinanttia. MAOLista löytyy joltain sivulta x determinantin laskukaavat ainakin 2*2- ja 3*3-neliömatriiseille. Sitä soveltamalla, pystynet ratkaisemaan ongelman myös tuolla kaavalla. Muistat vain purkaa determinantit sisältä ulos, samaan tapaan kuin sulut tavanomaisissa laskulausekkeissa.

Lukion matematiikkaan sopivampi ratkaisu lienee määrittää janojen laajennoksina syntyvät suorat ja niiden yhtälöt (muotoa y - y0 = k[x - x0]). Tämän jälkeen ne kirjoitetaan molemmat muotoon y = kx + b, sijoitetaan ensimmäiseen yhtälöön y:n paikalle toisen yhtälön oikea puoli, ja ratkaistaan x. Tämän jälkeen sijoittamalla saatu x:n arvo jompaankumpaan yhtälöön saadaan leikkauspisteen y-koordinaatti. Tämän jälkeen täytyy vielä tarkastaa, että saatu piste sijaitsee janoilla, eikä niiden jatkeilla.
CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES

CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
MaGetzUb
Guru
Posts: 1715
Joined: Sun Sep 09, 2007 12:35 pm
Location: Alavus

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by MaGetzUb »

Grandi wrote:Käänteinen puolalainen notaatio ei ole algoritmi vaan merkintätapa. Nyt jää vähän epäselväksi, mitä todella tahdot. Kenties laskufunktion, jossa infix-syöte muutetaan RPN-lausekkeeksi ennen laskemista?
Funktiokinhan on periaatteessa eräänlainen algoritmi tietotekniikassa. :)

Eikun haluaisin oikeastaan lausekkeen laskukoneen, joka toteuttaisi peruslaskutoimitukset nopeasti, eikä ottaisisi sulkeita huomioon. Voiko muuten RPN käyttää myös muitakin operaattoreita? =) Ajattelin et Potenssilla ei välttämättä saada oikeita vastauksia koska nehän pitää laskujärjestyksessä laskea ensinmäiseksi.. :o
Solar Eclipse
Meneillä olevat Projektit:
We're in a simulation, and God is trying to debug us.
User avatar
axu
Devoted Member
Posts: 854
Joined: Tue Sep 18, 2007 6:50 pm

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by axu »

MaGetzUb wrote:
Grandi wrote:Käänteinen puolalainen notaatio ei ole algoritmi vaan merkintätapa. Nyt jää vähän epäselväksi, mitä todella tahdot. Kenties laskufunktion, jossa infix-syöte muutetaan RPN-lausekkeeksi ennen laskemista?
Funktiokinhan on periaatteessa eräänlainen algoritmi tietotekniikassa. :)

Eikun haluaisin oikeastaan lausekkeen laskukoneen, joka toteuttaisi peruslaskutoimitukset nopeasti, eikä ottaisisi sulkeita huomioon. Voiko muuten RPN käyttää myös muitakin operaattoreita? =) Ajattelin et Potenssilla ei välttämättä saada oikeita vastauksia koska nehän pitää laskujärjestyksessä laskea ensinmäiseksi.. :o
Funktiota ja algoritmiä ei pidä sekoittaa toisiinsa - algoritmi on nimenomaan jokin toimintatapa, kun taasen funktiossa voidaan tehdä jotain tietyn algoritmin avulla. (itsekin kyllä sanoin tuolla aiemmin RPN-algoritmi :roll: )

"Perinteisellä" laskujärjestyksellä ei ole väliä RPN-muodossa, vaan lasketaan aina vasemmalta oikealle.
Jos tämä viesti on kirjoitettu alle 5 min. sitten, päivitä sivu. Se on saattanut jo muuttua :roll:
Image
Koodiapina
Forum Veteran
Posts: 2396
Joined: Tue Aug 28, 2007 4:20 pm

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by Koodiapina »

MaGetzUb wrote:
Grandi wrote:Käänteinen puolalainen notaatio ei ole algoritmi vaan merkintätapa. Nyt jää vähän epäselväksi, mitä todella tahdot. Kenties laskufunktion, jossa infix-syöte muutetaan RPN-lausekkeeksi ennen laskemista?
Funktiokinhan on periaatteessa eräänlainen algoritmi tietotekniikassa. :)
Käänteinen puolalainen notaatio on edelleenkin merkintätapa. On sitten eri asia, jos teet algoritmin/funktion, joka vaikkapa muuttaa infix-lausekkeen RPN:ksi. Opettele erottamaan nuo kaksi asiaa toisistaan.
MaGetzUb wrote:Eikun haluaisin oikeastaan lausekkeen laskukoneen, joka toteuttaisi peruslaskutoimitukset nopeasti, eikä ottaisisi sulkeita huomioon.
Nopea lausekkeen laskija C++:lla. Käsittelee kyllä myös sulkeet.
MaGetzUb wrote:Voiko muuten RPN käyttää myös muitakin operaattoreita? =) Ajattelin et Potenssilla ei välttämättä saada oikeita vastauksia koska nehän pitää laskujärjestyksessä laskea ensinmäiseksi.. :o
RPN perustuu siihen, että kaikki on pistetty valmiiksi oikeaan järjestykseen. Tuollaiset potenssilaskut menevät siinä missä mikä tahansa muukin laskutoimitus.
JATothrim
Tech Developer
Tech Developer
Posts: 606
Joined: Tue Aug 28, 2007 6:46 pm
Location: Kuopio

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by JATothrim »

xamuli wrote:Oon lukion ekalla, joten en tiedä miten matriiseja käytetään, mun pitäis saada laskettua kahden janan leikkauspiste ja löysin tämän, voisko joku neuvoa miten tolla sivulla olevat X = ... ja Y = ... hommat lasketaan (ovatko ne edes matriiseja?) ja onko helpompaa keinoa selvittää kahden janan leikkauspiste.

Nämä ovat siis ne mitä en osaa:

X =ImageY =Image
Kahden janan leikkaus piste voidaan laskea determinantilla. Sillä voidaan siten myös ratkaista myös yhtälöparit... (Itse teen näin, kun en jaksa pyöritellä yhtälöitä) Jaa.. tuosta kuvassa ei näyttäisi olevan ainottakaan matriisia, vaan determinantteja kaikki. (jotka kyllä ovat matriiseja tavallaan) ;) Matriisit ovat yleensä [yksirivinenjasarakkeinenmatriisi] suluissa, kun nuo ovat |xitseisarvotaijosisompihädeniindetermi| suluissa.

Code: Select all

|x1 y1|
|x2 y2|
determinantti purkautuu muotoon: x1*y2 - y1*x2
Ja kuten aina, matematiikassa ja algebrassa nuo x1, y1, x2 ja y2 voivat olla mitä lystää, esim. toisia determinantteja.
-On selkeästi impulsiivinen koodaaja joka...
ohjelmoi C++:lla rekursiivisesti instantioidun templaten, jonka jokainen instantiaatio instantioi sekundäärisen singleton-template-luokan, jonka jokainen instanssi käynistää säikeen tulostakseen 'jea'.
JATothrim
Tech Developer
Tech Developer
Posts: 606
Joined: Tue Aug 28, 2007 6:46 pm
Location: Kuopio

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by JATothrim »

doubles.. but:
MaGetzUb wrote:Miten sitten voisi tehdä laskukoneen jossa olisi perus +, -, /, * toiminnot ja algoritmina olisi Käänteinen Puolalainen Notaatio? :)
Pinolla kenties? :twisted: :lol: Ei vaan siis oikeasti, RPN-notaatiossa luet "2 3 1 2 + / ^" syötteen vasemalta oikealle, työntäen arvot pinoon. :| Kun törmät "2 3 1 2" jälkeen lasku operaatioon "+" poppaat pinosta operaattorin haluaman määrän tavaraa ("2" ja "1" siis) ja suoritat laskun. Tuloksen lykkäät takaisin pinoon. Tätä sitten toistetaan kunnes pinossa on jäljellä enää vastaus. Jos joltain laskuoperaattorilta loppuivat operandit kesken, kyseessä on virhe.

Note: " x y *" -> "y * x", tai en muista meneekö se sitenkin näin päin: "x y *" -> "x * y". Jompi kumpi, wikissä on hyvä artikkeli.

Bonuksena pakastuneesta kääntäjästä pätkä Infix -> RPN koodia:

Code: Select all

'Lausekkeen Tokenisaattori
Function TokenizeString(txt$)
	For i = 0 To SM_TotalKeywords
		MaxLen% = Max(MaxLen, Len( SM_Keyword(i) ) )
	Next i
	'Lisätään välimerkkejä avain sanojen ympärille
	processed_text$ = ""
	i = 1
	k = 1
	While i <= Len(txt)
	
		keyLen% = 1
		keyStr$ = ""
		
		For j = 0 To SM_TotalKeywords			
			For k = 1 To MaxLen
				If Mid(txt, i, k) = SM_Keyword(j) And k => keyLen
					keyLen = k
					keyStr$ = SM_Keyword(j)
					
				EndIf
			Next k
		Next j
		
		If keyStr <> ""
			processed_text = processed_text + " " + keyStr + " "
		Else
			processed_text = processed_text + Mid(txt, i, 1)
		EndIf
		
		i = i + keyLen
	Wend
	'Poistetaan ylimääräiset välimerkit
	For i = 0 To SM_TotalKeywords
		processed_text = Replace(processed_text, "  "+SM_Keyword(i), " "+SM_Keyword(i))
		processed_text = Replace(processed_text, SM_Keyword(i)+"  ", SM_Keyword(i)+" ")
		processed_text = Replace(processed_text, "  ", " ")
	Next i			
			
	Return processed_text
EndFunction
'Apufunktio: Lisää ulostuloon kunnes pinossa päällimäisenä olevan operaation prioriteetti
' on pienempi kuin annettu tai operaatio on arvo/muuttuja.
Function PopUntil(PRIORITY)
	iCS.ConvertStack = Last(ConvertStack)
	While iCS <> NULL
		If iCS\Priority => PRIORITY Or iCS\ID = OPR_VALUE Or iCS\ID = OPR_VARIABLE
			nOperand.OperatorStack = New(OperatorStack)
			nOperand\ID = iCS\ID
			nOperand\Value = iCS\Value
			Delete iCS
		Else
			Exit
		EndIf
		iCS = Last(ConvertStack)
	Wend
EndFunction

'Parsii lausekkeen (ja kaikki muut prioriteetin omaavat toimitukset)
Function ParseStatement(statement$)

	For i = 1 To CountWords(statement)
	
		operand$ = GetWord(statement, i)
		
		If Float(operand) <> 0.0 Or operand = "0" Or operand = "0.0"
			
			'Tarkistetaan negaatio: (joko suoritetaan negaatio tässä, 
			' tai muutetaan miinus negaatio operaatioksi)
			peek1.OperatorStack = Last(OperatorStack)
			If peek1 <> NULL
				peek2.OperatorStack = Before(peek1)
				
				If peek2 <> NULL
					peek3.OperatorStack = Before(peek2)
					
					If peek3 <> NULL
					
						If peek1\ID = OPR_MINUS And peek2\ID <> OPR_VALUE And peek3\ID <> OPR_VALUE
							'kyseessä ON negaatio, muutetaan.
							peek1\ID = OPR_NEGATE
						EndIf
						
					EndIf
					
				EndIf
				
			EndIf
			'Lisätään luku pinoon.
			nCS.ConvertStack = New(ConvertStack)
			nCS\Priority = PRI_MIN
			nCS\ID = OPR_VALUE
			nCS\Value = Float(operand)

		Else
			'Käsitellään operaattorit niiden prioriteetin mukaan.
			Select operand
			Case "&&", "||", "!", "!|"
				PopUntil(PRI_LOGIC)
				
				Select operand
				Case "&&": ID% = OPR_AND
				Case "||": ID = OPR_OR
				Case "!":  ID = OPR_NOT
				Case "!|": ID = OPR_XOR
				EndSelect
				
				nCS.ConvertStack = New(ConvertStack)
				nCS\Priority = PRI_LOGIC
				nCS\ID = ID
				
			Case "==", "!=", "<", "=>", ">", "=<"
				PopUntil(PRI_COMPARE)
				
				Select operand
				Case "==": ID% = OPR_EQUAL
				Case "!=": ID = OPR_INEQUAL
				Case "<":  ID = OPR_LESS
				Case "=>": ID = OPR_LESS_OR_EQUAL
				Case ">":  ID = OPR_GREATER
				Case "=<": ID = OPR_GREATER_OR_EQUAL
				EndSelect
				
				nCS.ConvertStack = New(ConvertStack)
				nCS\Priority = PRI_COMPARE
				nCS\ID = ID
				
			Case "-", "+"
				'Poistetaan pinosta mahdolliset suuremman prioriteetin omaavat operaatiot,
				'ja  lisätään ne ulostulo pinoon.
				PopUntil(PRI_MINUS_PLUS_NEGATE)
				'Lisätään operaatio "muunto"-pinoon
				If operand = "-" Then ID% = OPR_MINUS
				If operand = "+" Then ID% = OPR_PLUS
				nCS.ConvertStack = New(ConvertStack)
				nCS\Priority = PRI_MINUS_PLUS_NEGATE
				nCS\ID = ID
				
			Case "*", "/"
				PopUntil(PRI_MULTIPLY_DIVISION)
				'Lisätään operaatio "muunto"-pinoon
				If operand = "*" Then ID% = OPR_MULTIPLY
				If operand = "/" Then ID% = OPR_DIVISION
				nCS.ConvertStack = New(ConvertStack)
				nCS\Priority = PRI_MULTIPLY_DIVISION
				nCS\ID = ID
				
			Case "^"
				PopUntil(PRI_POWER)
				'Lisätään operaatio "muunto"-pinoon
				nCS.ConvertStack = New(ConvertStack)
				nCS\Priority = PRI_POWER
				nCS\ID = OPR_POWER
				
			Case "("
				'Lisätään suoraan pinoon
				nCS.ConvertStack = New(ConvertStack)
				nCS\Priority = PRI_MIN
				nCS\ID = OPR_BRACKET
				
			Case ")"
				'Lisätään "muunto" pinosta ulostuloon kunnes saavutetaan "(" merkki
				iCS.ConvertStack = Last(ConvertStack)
				While iCS <> NULL
					
					If iCS\ID <> OPR_BRACKET
						nOperand.OperatorStack = New(OperatorStack)
						nOperand\ID = iCS\ID
						nOperand\Value = iCS\Value
						Delete iCS
					Else
						Exit
					EndIf
					iCS.ConvertStack = Last(ConvertStack)
				Wend
				If iCS <> NULL Then Delete iCS Else MakeError "Non equal Brackets!" 'poistetaan vielä "("
				
			Case "="
				PopUntil(PRI_MIN)
				nCS.ConvertStack = New(ConvertStack)
				nCS\Priority = PRI_MIN
				nCS\ID = OPR_SETVARIABLE
				
			Default
				'Sana ei ollut operaattori eikä numero, joten tarkistetaan onko se muuttuja.
				For iVar.Variable = Each Variable
					If Lower(operand) = iVar\NameID
						'Muuttuja nimi ON olemassa, lisätään pinoon.
						nCS.ConvertStack = New(ConvertStack)
						nCS\ID = OPR_VARIABLE
						nCS\Priority = PRI_MIN
						nCS\Value = ConvertToInteger(iVar)
						Exit
					EndIf
				Next iVar
				
			EndSelect

		EndIf
		
	Next i
	'Popataan loput.
	iCS.ConvertStack = Last(ConvertStack)
	While iCS <> NULL
		'Thyjennetään muuntopino ja tarkistetaan virheet.
		If iCS\ID = OPR_BRACKET Then MakeError "Non equal Brackets!"
		nOperand.OperatorStack = New(OperatorStack)
		nOperand\ID = iCS\ID
		nOperand\Value = iCS\Value
		Delete iCS
		iCS.ConvertStack = Last(ConvertStack)

	Wend
EndFunction
-On selkeästi impulsiivinen koodaaja joka...
ohjelmoi C++:lla rekursiivisesti instantioidun templaten, jonka jokainen instantiaatio instantioi sekundäärisen singleton-template-luokan, jonka jokainen instanssi käynistää säikeen tulostakseen 'jea'.
MaGetzUb
Guru
Posts: 1715
Joined: Sun Sep 09, 2007 12:35 pm
Location: Alavus

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by MaGetzUb »

Taisin ratkaista ongelmani:

Code: Select all



Print "RPN f: "+DSG_RPN("(2*0.3/5*(4+3)*2+100)/10")
Print "Not RPn: "+(2*0.3/5*(4+3)*2+100)/10
WaitKey


Function DSG_RPN(lasku$)
    Dim numbers(Len(lasku)) As Float 
    Dim operators(Len(lasku)) As String 

    //Aloitetaan lausekkeen läpikäynti
    For i = 1 To Len(lasku$)
    
        //Osuttiinko numeroon?
        char$ = Mid(lasku$, i, 1) 
        
        //Lähdetään tarkistamaan merkkijonoa nyt numeron osumakohdasta eteenpäin, jos lötyi
        //lisää numeroita, niin lisätään niitä merkkijonoon, joka sitten käännetään float-arvoksi.
        
        //Luodaan luvut muistiin
        If Asc(char) => 48 And Asc(char) =< 57 Then
            nums = nums + 1 
            numero$ = char
            nextchar = i
            //Luetaan eteenpäin lasku-merkkijonomuuttujaa.
            While Not die 
                nextchar = nextchar + 1
                If (Asc(Mid(lasku$, nextchar, 1)) => 48 And Asc(Mid(lasku$, nextchar, 1)) =< 57) Or Asc(Mid(lasku$, nextchar, 1)) = 46 Then
                    numero = numero + Mid(lasku$, nextchar, 1) 
                Else 
                    Exit 
                EndIf 
            Wend 
            die = False 
            numbers(nums) = Float(numero)
            i = nextchar
        EndIf 
    Next i
    For i = 1 To Len(lasku$)
        //Haetaan operaattorit
        char$ = Mid(lasku$, i, 1) 
        If Asc(char) = 43 Or Asc(char) = 45 Or Asc(char) = 42 Or Asc(char) = 47 Or Asc(char) = 94 Or Asc(char) = 61 Or Asc(char) = 62 Then 
            ops = ops + 1
            operators(ops) = char
        EndIf     
    Next i
    
    kohta = 1
    While kohta =< ops
        Print numbers(1)
        Select operators(kohta)
        Case "+"
            numbers(1) = numbers(1) + numbers(kohta+1)
        Case "-"
            numbers(1) = numbers(1) - numbers(kohta+1)
        Case "/"
            numbers(1) = numbers(1) / numbers(kohta+1)
        Case "*"
            numbers(1) = numbers(1) * numbers(kohta+1)
        Case "^"
            numbers(1) = numbers(1) ^ numbers(kohta+1)
        EndSelect 
         
        kohta = kohta + 1
    Wend
    Return numbers(1)
EndFunction  
Joissakin kohtaa CoolBasic tuntuu kusevan noita laskuja, koska lasken vaiheittain laskimella laskut joita laitan RPN() -funktiooni, ja saadut tulokset täsmäävät laskimen kanssa keskenään.
Solar Eclipse
Meneillä olevat Projektit:
We're in a simulation, and God is trying to debug us.
Koodiapina
Forum Veteran
Posts: 2396
Joined: Tue Aug 28, 2007 4:20 pm

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by Koodiapina »

MaGetzUb wrote:Taisin ratkaista ongelmani:

Code: Select all



Print "RPN f: "+DSG_RPN("(2*0.3/5*(4+3)*2+100)/10")
Print "Not RPn: "+(2*0.3/5*(4+3)*2+100)/10
WaitKey


Function DSG_RPN(lasku$)
    Dim numbers(Len(lasku)) As Float
    Dim operators(Len(lasku)) As String

    //Aloitetaan lausekkeen läpikäynti
    For i = 1 To Len(lasku$)
   
        //Osuttiinko numeroon?
        char$ = Mid(lasku$, i, 1)
       
        //Lähdetään tarkistamaan merkkijonoa nyt numeron osumakohdasta eteenpäin, jos lötyi
        //lisää numeroita, niin lisätään niitä merkkijonoon, joka sitten käännetään float-arvoksi.
       
        //Luodaan luvut muistiin
        If Asc(char) => 48 And Asc(char) =< 57 Then
            nums = nums + 1
            numero$ = char
            nextchar = i
            //Luetaan eteenpäin lasku-merkkijonomuuttujaa.
            While Not die
                nextchar = nextchar + 1
                If (Asc(Mid(lasku$, nextchar, 1)) => 48 And Asc(Mid(lasku$, nextchar, 1)) =< 57) Or Asc(Mid(lasku$, nextchar, 1)) = 46 Then
                    numero = numero + Mid(lasku$, nextchar, 1)
                Else
                    Exit
                EndIf
            Wend
            die = False
            numbers(nums) = Float(numero)
            i = nextchar
        EndIf
    Next i
    For i = 1 To Len(lasku$)
        //Haetaan operaattorit
        char$ = Mid(lasku$, i, 1)
        If Asc(char) = 43 Or Asc(char) = 45 Or Asc(char) = 42 Or Asc(char) = 47 Or Asc(char) = 94 Or Asc(char) = 61 Or Asc(char) = 62 Then
            ops = ops + 1
            operators(ops) = char
        EndIf     
    Next i
   
    kohta = 1
    While kohta =< ops
        Print numbers(1)
        Select operators(kohta)
        Case "+"
            numbers(1) = numbers(1) + numbers(kohta+1)
        Case "-"
            numbers(1) = numbers(1) - numbers(kohta+1)
        Case "/"
            numbers(1) = numbers(1) / numbers(kohta+1)
        Case "*"
            numbers(1) = numbers(1) * numbers(kohta+1)
        Case "^"
            numbers(1) = numbers(1) ^ numbers(kohta+1)
        EndSelect
         
        kohta = kohta + 1
    Wend
    Return numbers(1)
EndFunction  
Ei näin.

RPN on edelleenkin merkintätapa. Ei mikään laskufunktioalgoritmi, kuten kaikesta päätellen edelleenkin luulet. Jos tahdot tehdä puhtaasti vain infix-lausekkeita laskevan laskufunktion, et edes tarvitse mitään RPN:ää. Unohda se kokonaan. RPN tulee kysymykseen silloin, jos sinun pitää laskea/suorittaa jokin lauseke tulevaisuudessa mahdollisimman nopeasti, kuten tulkattavissa ohjelmointikielissä, joissa RPN-lausekkeet sopivat hyvin tavukoodiksi.
MaGetzUb wrote:Joissakin kohtaa CoolBasic tuntuu kusevan noita laskuja, koska lasken vaiheittain laskimella laskut joita laitan RPN() -funktiooni, ja saadut tulokset täsmäävät laskimen kanssa keskenään.
Infix-lausekkeissa pätee infix-lausekkeiden laskujärjestys. Se opetetaan jo ala-asteella. Et voi laskea niitä samalla tavalla suoraviivaisesti kuten RPN-lausekkeita. CoolBasic laskee laskut aivan oikein, sinä ja laskufunktiosi väärin.

Ei tarvitse heittää laskufunktiollesi kuin vain 2+2*10 kun vastaus jo meneekin täysin metsään :D
MaGetzUb
Guru
Posts: 1715
Joined: Sun Sep 09, 2007 12:35 pm
Location: Alavus

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by MaGetzUb »

Tarvitsen skriptisysteemiini nopeaa lausekkeen laskujärjestelmää. :) Ja niin ymmärsin kyllä sen ettei RPN ole algoritmi.
Solar Eclipse
Meneillä olevat Projektit:
We're in a simulation, and God is trying to debug us.
Koodiapina
Forum Veteran
Posts: 2396
Joined: Tue Aug 28, 2007 4:20 pm

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by Koodiapina »

MaGetzUb wrote:Tarvitsen skriptisysteemiini nopeaa lausekkeen laskujärjestelmää. :)
Aiemmin et puhunut mitään skriptisysteemeistä, vaan vain lausekkeen laskijasta. Ei kannata kysyä apua, jos ei tiedä mitä haluaa.

Ja hommahan on erittäin simppeli:
1. Teet kääntäjän, joka muuttaa lausekkeen RPN-muotoiseksi.
2. Teet tulkin, joka laskee/suorittaa RPN-lausekkeita.

JATothrim laittoikin jo esimerkkikoodia, jota voit tutkia.
MaGetzUb
Guru
Posts: 1715
Joined: Sun Sep 09, 2007 12:35 pm
Location: Alavus

Re: Matriisitulo ja muuta vaikeaa matikkaa.

Post by MaGetzUb »

Grandi wrote:
MaGetzUb wrote:Tarvitsen skriptisysteemiini nopeaa lausekkeen laskujärjestelmää. :)
Aiemmin et puhunut mitään skriptisysteemeistä, vaan vain lausekkeen laskijasta. Ei kannata kysyä apua, jos ei tiedä mitä haluaa.

Ja hommahan on erittäin simppeli:
1. Teet kääntäjän, joka muuttaa lausekkeen RPN-muotoiseksi.
2. Teet tulkin, joka laskee/suorittaa RPN-lausekkeita.

JATothrim laittoikin jo esimerkkikoodia, jota voit tutkia.
Koodi oli sekavaa, ja pukkasi heti virhettä. Ja kummasta tässä nyt puhutaan RPN:ä vai lausekkeen laskijasta?
Solar Eclipse
Meneillä olevat Projektit:
We're in a simulation, and God is trying to debug us.
Post Reply