Ready64 Forum
Commodore 64 => Programmazione, Grafica e Musica => Topic aperto da: Roberto - 14 Giugno 2004, 15:23:44
-
Sto facendo delle operazioni con i numeri casuali e le stringhe. Alla fine però ho dei problemi. Chi mi aiuta a capire come funziona la conversione di un numero in una stringa? Provo a spiegarmi con l'esempio pratico.
Per prima cosa creo un numero casuale compreso in un range tra 1 e 999.999
x=int(rnd(1)*10^6)
Ovviamente questa linea mi restituisce risultati del tipo:
999999
999998
999997
...
...
...
...
5320
5319
5318
...
eccetera.
Successivamente, ho la necessità di convertire il numero precedentemente generato in una stringa, e per farlo utilizzo normalmente:
x$=str$(x)
(A questo punto sorge il problema.)
Supponiamo che il numero casuale sia di 6 cifre:
123456
la stringa corrispondente sarà:
"123456"
Ma se invece il numero generato casualmente è di 5 cifre:
12345
la stringa che viene generata sarà:
"[SPAZIO]12345"
Mentre, almeno personalmente, mi aspettavo un più logico:
"12345"
Senza spazi eccedenti.
Le domande sono due.
La prima è come mai si forma quello spazio.
La seconda è come riuscire a convertire il numero senza generare lo spazio.
Ultima cosa:
Ho trovato una soluzione che aggira il problema. IL guaio è che la routine in questione è lunga circa 20 linee di Basic: decisamente troppo per i miei gusti.
Spero che la domanda non sia di livello troppo infimo :hail:
:stordita:
-
Puoi provare così?
10 A = 12345
20 A$ = STR$(A)
30 A$ = RIGHT$(A$,(LEN(A$) - 1))
Dovrebbe funzionare... Non lo posso controllare per te perchè devo scappere! Ciauz
-
Puoi provare così?
10 A = 12345
20 A$ = STR$(A)
30 A$ = RIGHT$(A$,(LEN(A$) - 1))
Dovrebbe funzionare... Non lo posso controllare per te perchè devo scappere! Ciauz
Direi di si!
In pratica basta cancellare il primo carattere che è sempre uno spazio, giusto?
Ad ogni modo, non capisco come mai la conversione in stringa aggiunga quel famigerato "spazio".... :fagiano:
-
Ad ogni modo, non capisco come mai la conversione in stringa aggiunga quel famigerato "spazio".... :fagiano:
metti -1 e capirai :=)
-
Ad ogni modo, non capisco come mai la conversione in stringa aggiunga quel famigerato "spazio".... :fagiano:
metti -1 e capirai :=)
Già.... Hai proprio ragione! Quindi sarebbe più corretto scrivere:
10 A = 12345
20 IF A < 0 THEN GOTO 40
25 A$ = STR$(A)
30 GOTO 60
40 A$ = STR$(A)
50 A$ = RIGHT$(A$,(LEN(A$) - 1))
60 REM NUMERO CONVERTITO
giusto? Così si evita di tagliare un carattere "-" qualora il numero fosse negativo!
-
20 IF A < 0 THEN GOTO 40
dov'è il 40 nel listato??
---
ora si ;)
-
20 IF A < 0 THEN GOTO 40
25 A$ = STR$(A)
30 GOTO 60
40 A$ = STR$(A)
Codice ridondante. Lo so, e' solo una riga, ma su 6 e' gia' una buona percentuale. Se si ignora una volta poi vengono fuori programmi inutilmente pieni di ripetizioni. ;)
20 A$ = STR$(A)
30 if a<0 then A$ = RIGHT$(A$,(LEN(A$) - 1))
-
20 IF A < 0 THEN GOTO 40
25 A$ = STR$(A)
30 GOTO 60
40 A$ = STR$(A)
Codice ridondante. Lo so, e' solo una riga, ma su 6 e' gia' una buona percentuale. Se si ignora una volta poi vengono fuori programmi inutilmente pieni di ripetizioni. ;)
20 A$ = STR$(A)
30 if a<0 then A$ = RIGHT$(A$,(LEN(A$) - 1))
Giusto...
:ciauz:
-
il numero casuale è sempre superiore ad 1, quindi perchè fare il controllo:
IF A < 0
:fagiano:
-
Hai ragione, ma era per fare una routine generica, credo.
Tra l'altro manco me ne ero accorto dell'errore logico:
30 if a>=0 then A$ = RIGHT$(A$,(LEN(A$) - 1))
cioe': se il numero e' POSITIVO togli lo spazio sulla sinistra della stringa
Ma tutto questo non l'avevi gia' fatto per i punteggi di SpaceCrap?
-
Hai ragione, ma era per fare una routine generica, credo.
Tra l'altro manco me ne ero accorto dell'errore logico:
30 if a>=0 then A$ = RIGHT$(A$,(LEN(A$) - 1))
cioe': se il numero e' POSITIVO togli lo spazio sulla sinistra della stringa
Ah, ok :)
Ma tutto questo non l'avevi gia' fatto per i punteggi di SpaceCrap?
Qui il problema si presenta in maniera molto diversa.
L'uso dei comandi STR$, RIGHT$, LEFT$ è semplice, molto semplice, ma qui mi si presentava un problema che non sapevo risolvere nè capire, quello dello [SPAZIO] in eccesso nelle stringhe :)
Un'altra domanda sulle funzioni casuali: sono poi casuali davvero??
Ogni volta che faccio ripartire l'emulatore mi dà lo stesso numero casuale! :confused:
-
Un'altra domanda sulle funzioni casuali: sono poi casuali davvero??
Ogni volta che faccio ripartire l'emulatore mi dà lo stesso numero casuale!
Dipende dal segno del parametro di RND.
Se usi come parametro sempre un certo numero negativo,RND genera sempre lo stesso numero casuale.
Se usi come parametro sempre un certo numero positivo,ogni volta che fai ripartire il C64 viene generata una stessa sequenza di numeri casuali.
Se usi come parametro uno 0,vengono generate sequenze semi-casuali di numeri, sempre diverse tra loro.
-
Un'altra domanda sulle funzioni casuali: sono poi casuali davvero??
Ogni volta che faccio ripartire l'emulatore mi dà lo stesso numero casuale!
Dipende dal segno del parametro di RND.
Se usi come parametro sempre un certo numero negativo,RND genera sempre lo stesso numero casuale.
Se usi come parametro sempre un certo numero positivo,ogni volta che fai ripartire il C64 viene generata una stessa sequenza di numeri casuali ( dipendente dallo stato dell'hardware del C64 ).
Se usi come parametro uno 0,vengono generate sequenze semi-casuali di numeri, sempre diverse tra loro.
SBONK! :confused:
Ero convinto che il seme RANDOM fosse preso dal timer di sistema!
Mi confondo con qualche altro hardware, forse?
-
Ero convinto che il seme RANDOM fosse preso dal timer di sistema!
Sì,ma solo nel caso di RND(0) (almeno,secondo la Guida del programmatore... :) )
-
Anche il disassemblato del Kernal sembra confermare questa tesi
E0A5 A0 04 LDY #$04
E0A7 B1 22 LDA ($22),Y
E0A9 85 62 STA $62
E0AB C8 INY
E0AC B1 22 LDA ($22),Y
E0AE 85 64 STA $64
E0B0 A0 08 LDY #$08
E0B2 B1 22 LDA ($22),Y
E0B4 85 63 STA $63
E0B6 C8 INY
E0B7 B1 22 LDA ($22),Y
E0B9 85 65 STA $65
E0BB 4C E3 E0 JMP $E0E3
-
Anche il disassemblato del Kernal sembra confermare questa tesi
]
So di andare un pò OT ma lo potresti tradurre? (così vedo un pò di capire il linguaggio macchina)
E0A5 A0 04 LDY #$04
E0A7 B1 22 LDA ($22),Y
E0A9 85 62 STA $62
E0AB C8 INY
E0AC B1 22 LDA ($22),Y
E0AE 85 64 STA $64
E0B0 A0 08 LDY #$08
E0B2 B1 22 LDA ($22),Y
E0B4 85 63 STA $63
E0B6 C8 INY
E0B7 B1 22 LDA ($22),Y
E0B9 85 65 STA $65
E0BB 4C E3 E0 JMP $E0E3
La prima colonna è l'offset, giusto? difatti l'istruzione, alla fine, JUMP punta ad un offset E0E3?
La seconda colonna indica il codice mnemonico o il token? (o nessuno dei due, vado a memoria). Ossia l'identificativo esadecimale dell'istruzione.
Quindi
STA = 85
LDA = B1
JMP = 4C
...
La terza l'istruzione, in assembly C64, giusto?
Nello specifico cosa fa questa porzione di codice? JMP salta verso qualche parte, e gli altri comandi?
-
La prima colonna è l'offset, giusto?
E' l'indirizzo del primo byte dell'istruzione.
difatti l'istruzione, alla fine, JUMP punta ad un offset E0E3?
Esatto,salta all'istruzione che comincia a $E0E3.
La seconda colonna indica il codice mnemonico o il token?
Proprio così ;)
La terza l'istruzione, in assembly C64, giusto?
La terza e quarta colonna indicano gli eventuali parametri dell'istruzione ( byte basso/alto di un indirizzo,valore da caricare,salto relativo,eccetera... )
Nello specifico cosa fa questa porzione di codice?
E' la porzione di codice eseguita quando il parametro della RND è 0.
In pratica,legge i valori del timer e del clock di sistema e li mette nei byte di mantissa ( i byte di mantissa contengono il risultato numerico di funzioni e varie operazioni aritmetiche... )
-
Ho provato a commentare il disassemblato della RND(). Ci sono un paio di punti "misteriosi" dove fa i calcoli perche' alcune JSR vanno a meta' di alcune funzioni di calcolo e non dall'inizio...
;---------------------------
; float numbers for RND
;---------------------------
E08D .BY $98,$35,$44,$7A,$00
E092 .BY $68,$28,$B1,$46,$00
;---------------------------
; RND function
;---------------------------
E097 20 2B BC JSR $BC2B ; get sign of float accu in A
E09A 30 37 BMI $E0D3 ; negative ?
E09C D0 20 BNE $E0BE ; positive ?
;---------------------------
; if zero get timer as seed
;---------------------------
E09E 20 F3 FF JSR $FFF3 ; now YX = $DC00
E0A1 86 22 STX $22
E0A3 84 23 STY $23
E0A5 A0 04 LDY #$04
E0A7 B1 22 LDA ($22),Y; ($22)+y points to $DC04
E0A9 85 62 STA $62 ; Timer A: Low-Byte
E0AB C8 INY
E0AC B1 22 LDA ($22),Y; $DC05 Timer A: High-Byte
E0AE 85 64 STA $64
E0B0 A0 08 LDY #$08
E0B2 B1 22 LDA ($22),Y; $DC08 Time-of-Day Clock:
E0B4 85 63 STA $63 ; 1/10 Seconds
E0B6 C8 INY
E0B7 B1 22 LDA ($22),Y; $DC09 Time-of-Day Clock:
E0B9 85 65 STA $65 ; Seconds
E0BB 4C E3 E0 JMP $E0E3
;---------------------------
;if positive starts here
;---------------------------
E0BE A9 8B LDA #$8B ; lots of pseudo operations here
E0C0 A0 00 LDY #$00 ; first, get last rnd seed number
; from $008B
E0C2 20 A2 BB JSR $BBA2 ; divide?
E0C5 A9 8D LDA #$8D ; constant float #1, ptr @ $E08D
E0C7 A0 E0 LDY #$E0
E0C9 20 28 BA JSR $BA28 ; minus/times?
E0CC A9 92 LDA #$92 ; constant float #2, ptr @ $E092
E0CE A0 E0 LDY #$E0
E0D0 20 67 B8 JSR $B867 ; add float indexed by AY
;--------------------------- ; to float accu
;if negative starts here
;---------------------------
E0D3 A6 65 LDX $65 ; 0061-0066 : FAC
E0D5 A5 62 LDA $62 ; (Main Floating point Accu)
E0D7 85 65 STA $65 ; here swaps mantissa bytes
E0D9 86 62 STX $62
E0DB A6 63 LDX $63
E0DD A5 64 LDA $64
E0DF 85 63 STA $63
E0E1 86 64 STX $64
;---------------------------
E0E3 A9 00 LDA #$00
E0E5 85 66 STA $66 ; 0=no sign
E0E7 A5 61 LDA $61 ; exponent
E0E9 85 70 STA $70
E0EB A9 80 LDA #$80 ; negative exponent?
E0ED 85 61 STA $61
E0EF 20 D7 B8 JSR $B8D7 ; round?
E0F2 A2 8B LDX #$8B
E0F4 A0 00 LDY #$00
E0F6 4C D4 BB JMP $BBD4; store float accu in XY ($008B)