 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Keks
Anmeldungsdatum: 03.11.2007 Beiträge: 156 Wohnort: Dose
|
Verfasst am: 30.10.2008, 15:50 Titel: Übergroße DOUBLE-Zahlen |
|
|
Moin, der Keks kommt auch mal wieder aus der Dose.
Ich stehe grade vor einem kleinen Problem.
Ich habe vor, eine Grafik zu zeichnen, sie mit GET zu speichern und dann in eine Datei zu schreiben.
Als Datentyp für das Speicherarray habe ich DOUBLE genommen, nur reicht das nicht aus (Ein String geht nicht wg Datentypen).
Es kommt so etwas raus: 4.305839490282825D-294
Was kann man dagegen tun?
Noch ein Problem ist, diese Zahl da oben ist nicht zwischen 4 und 5 wie es scheint, also wird nichts aus Annäherung.
Danke^^ _________________ RUN "brain.exe"
Datei nicht gefunden |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 30.10.2008, 18:03 Titel: |
|
|
Wie das genau unter QBASIC funktioniert, weiß ich jetzt leider nicht (unter FreeBASIC geht das einfacher ), aber ich dachte, dass INTEGER der Array-Typ der Wahl ist. "Zu klein" kann insofern nicht sein, weil du ja nur das Array genügend groß machen musst. Du nimmst doch auch wirklich ein Array und nicht nur eine Einzelzahl?
4.305839490282825D-294 ist übrigens nicht besonders groß sondern im Gegenteil sehr sehr klein.  _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
Sebastian Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
Verfasst am: 30.10.2008, 20:22 Titel: Re: Übergroße DOUBLE-Zahlen |
|
|
Hallo!
Keks hat Folgendes geschrieben: | Ich habe vor, eine Grafik zu zeichnen, sie mit GET zu speichern und dann in eine Datei zu schreiben.
Als Datentyp für das Speicherarray habe ich DOUBLE genommen, nur reicht das nicht aus (Ein String geht nicht wg Datentypen).
Es kommt so etwas raus: 4.305839490282825D-294 |
Wenn du einen Bildschirmbereich mit GET in ein Datenfeld (Array) eingelesen hast, kannst du das Bild nicht einfach durch PRINTen der einzelnen Arrayelemente ausgeben! Ein Arrayelement speichert bei Verwendung des Datentyps Double 8 Byte (>1 Pixel!). Durch ein einfaches PRINT erhältst du da keine Pixelfarbinformation im Bereich von 0 bis 15 bzw. 0 bis 255! Die 8 Byte an Grafikdaten werden, wenn du sie PRINTest, einfach als normale Gleitkommazahl vom Typ DOUBLE interpretiert und in Scientific Notation ausgegeben, obwohl es sich um keine Gleitkommazahldaten handelt! Es werden bei GET lediglich die reservierten Bytes der Arrayeinträge mit Grafikdaten vollgeschrieben. Der Datentyp spielt für den Dateninhalt keine Rolle, lediglich für die Eintraganzahl im Array (wenn du INTEGER (2 Bytes) nimmst, brauchst du doppelt so viele Einträge wie bei SINGLE (4 Bytes)). Demzufolge solltest du die Grafikdaten auch nicht als formatierte Zahlen in eine Datei ausgeben lassen (z.B. mit PRINT #nr, ...), sondern im Zugriffsmodus BINARY als Rohdaten in der Datei ablegen (mit PUT).
Viele Grüße!
Sebastian _________________
Die gefährlichsten Familienclans | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen! |
|
Nach oben |
|
 |
Keks
Anmeldungsdatum: 03.11.2007 Beiträge: 156 Wohnort: Dose
|
Verfasst am: 30.10.2008, 21:39 Titel: |
|
|
Ok das Schreiben geht schonmal, nur das Einlesen will nicht.
Code: | DIM kreis(99), kreis2(99)
CIRCLE (100, 100), 10
GET (90, 90) - (110, 110), kreis
OPEN "save/test.txt" FOR BINARY AS #1
PUT #1, , kreis
CLOSE #1
OPEN "save/test.txt" FOR BINARY AS #2
GET #2, , kreis2
CLOSE #2
PUT (590, 190), kreis2, PSET |
Was stimmt an dem GETten nicht? _________________ RUN "brain.exe"
Datei nicht gefunden |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 30.10.2008, 21:43 Titel: |
|
|
Klar geht das nicht, du deklarierst viel zu wenig platz für den kreis.
die formel, um die benötigte größe des arrays zu bekommen, lautet:
groesse_in_bytes = (x2 - x1 + 1) * (y2 - y1 + 1)
die kleinstmögliche einheit in qbasic ist integer, also würde ich das feld so deklarieren:
Code: |
dim kreis(int(21*21/2)) as integer
|
_________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
St_W

Anmeldungsdatum: 22.07.2007 Beiträge: 956 Wohnort: Austria
|
Verfasst am: 30.10.2008, 21:51 Titel: |
|
|
@Jojo: genug platz für den kreis ist schon, da der folgende code funktioniert (oder liege ich da falsch?):
Code: |
DIM kreis(0 TO 99) AS SINGLE 'Single ist Standard, wenn kein DEFINT erfolgt ist, siehe obiges bsp
DIM kreis2(0 TO 99) AS SINGLE
SCREEN 12
CIRCLE (100, 100), 10
GET (90, 90)-(110, 110), kreis
'...
PUT (590, 190), kreis, PSET
SLEEP
|
Ich glaube, dass beim Speichern des Arrays nur nur dessen Pointer auf den Index (oder der Index selbst) gespeichert wird - jedenfalls nicht das ganze Array.
2 Begründungen:
- Die erzeugte Datei ist viel zu klein (wenn das ganze Array gespeichert werden würde, müsste die datei größer sein)
- folgender Code funktioniert
Code: |
DIM kreis(0 TO 99) AS SINGLE
DIM kreis2(0 TO 99) AS SINGLE
SCREEN 12
CIRCLE (100, 100), 10
GET (90, 90)-(110, 110), kreis
KILL "test.txt"
OPEN "test.txt" FOR BINARY AS #1
FOR q = 0 TO 99
PUT #1, , kreis(q)
NEXT
CLOSE #1
OPEN "test.txt" FOR BINARY AS #2
FOR q = 0 TO 99
GET #2, , kreis2(q)
NEXT
CLOSE #2
PUT (590, 190), kreis2, PSET
SLEEP
|
So zu speichern ist jedoch relativ langsam. Ich würde die Verwendung der Befehle BSAVE und BLOAD empfehlen.
Ich denke es wäre z.B so möglich (Code ungetestet):
Code: |
'Zum Speichern
DEF SEG = varseg(kreis(0))
BSAVE "test.txt", VARPTR(kreis(0)), 100*4
DEF SEG
'Zum Laden
DEF SEG = varseg(kreis2(0))
BLOAD "test.txt", VARPTR(kreis2(0))
DEF SEG
|
Wie gesagt habe ich letzteres nicht ausprobiert. Bein Arrays bin ich mir generell immer unsicher, da ich die physikalische Anordnung nicht immer weiß (Es muss nicht sein, dass das ganze Array linear hintereinander im RAM ist). Ebenso unsicher bin ich mir beim Array-Index. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
Zuletzt bearbeitet von St_W am 30.10.2008, 22:24, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 30.10.2008, 22:13 Titel: |
|
|
gerade wegen single ist kein platz.
100*4bytes = 400, benötigt werden aber 441 bytes. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
Keks
Anmeldungsdatum: 03.11.2007 Beiträge: 156 Wohnort: Dose
|
Verfasst am: 30.10.2008, 22:35 Titel: |
|
|
Ja es geht mit BLOAD un BSAVE
Speicher habe ich auf 441 angepasst.
Was macht denn genau das varptr, wofür benutzt man das sonst noch? _________________ RUN "brain.exe"
Datei nicht gefunden |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 30.10.2008, 22:50 Titel: |
|
|
varptr gibt die position der variable im speicher zurück. nennt man auch pointer. pointer sind lustig! _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
St_W

Anmeldungsdatum: 22.07.2007 Beiträge: 956 Wohnort: Austria
|
Verfasst am: 30.10.2008, 23:06 Titel: |
|
|
^ ^ Als kleine Veranschaulichung (Segmentgrößen, usw. zur Anschaulichkeit nicht originalgetreu)
//EDIT: Fehler in der Grafik entdeckt: Segmente sollten gleich groß sein (0.Segment ist um 1 Byte zu groß geworden). EDIT-ENDS//
VARPTR gibt den Offset zurück (in diesem Fall 2). Die Offset-Adresse bezieht sich immer auf ein bestimmtes Segment.
VARSEG gibt das Segment zurück (in diesem Fall 1)
So kann man die absolute Position der Variable im Speicher bestimmen.
Mit BSAVE wird einfach der Speicherinhalt ab dieser Adresse in eine Datei geschrieben, mit BLOAD wird der Dateiinhalt wieder in den Speicher geladen.
Wenn du jetzt ein INTEGER Array verwendest belegt jede Instanz von kreis jeweils 2 Bytes im Speicher. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|