[Turbo Pascal] Een probleem, de 32768 limiet

Pagina: 1
Acties:

  • maratropa
  • Registratie: Maart 2000
  • Niet online
Een jaar of wat geleden kwam ik per ongeluk in contact met turbo pascal, en heb daar wat mee gespeeld, ik ben geen programmeur ofzo, dus als ik dom overkom, sorry. Ik heb daar voor mijn Pa een programma geschreven wat grafieken maakt van formules.

Ergens in het prgramma zit een loop, die elke stap een waarde voor de grafiek berekend, zoiets als

for VAR = 1 to X do:

VAR is een integer variabele, en X een integer nummer.

Nu gaat Turbo pascal over de zeik als X groter is dan 32768, dus 2 tot de macht 15 -1.

Dit lijkt me niet toevallig, maar iets binairs of iets met bits ofzo, waar ik dus weinig vanaf weet. Het liefst zouden we 300.000 berkeningen willen maken in 1 run, maar dat gaat dus nu niet.

Iemand uitleg of een tip?

specs


  • Cavorka
  • Registratie: April 2003
  • Laatst online: 27-03-2018

Cavorka

Internet Entrepreneur

Misschien tussenresultaat maken na ~30000 runs? En dan doorgaan met de volgende ~30000, en dan uiteindelijk alle tussenresultaten wegen en optellen?

Zoiets als (pseudo code):
for VAR2 = 1 to ceil(TOTALRUNS / 3000) do {
for VAR = VAR2 * 30000 to X do {
}
}

Wat voor berekening gaat hem om?

offtopic:
PS: Gegroet fellow 3d'er! ;)

[ Voor 25% gewijzigd door Cavorka op 22-11-2003 15:16 ]

the-blueprints.com - The largest free blueprint collection on the internet: 50000+ drawings.


  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 10-08 15:15
Het lijkt er sterk op dat je een 16-bits signed integer gebruikt. Dat betekent 15 bits voor het getal en 1 bit voor het teken. Dus je kan niet hoger komen dan de genoemde waarde. Het antwoord hierop is het zoeken naar grotere integers, bijvoorbeeld 32 bits. Nu ken ik geen Turbo Pascal, maar zoiets zou bij de documentatie moeten zitten.

Misschien heb je hier iets aan:

http://www.google.nl/sear...all+number&hl=nl&ie=UTF-8
For most purposes, you will always use `Integer', a signed integer type which has the "nat- ural" size of such types for the machine. On most machines GPC runs on, this is a size of 32 bits, so `Integer' usually has a range of `-2147483648..2147483647'

[ Voor 48% gewijzigd door Infinitive op 22-11-2003 15:15 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • elevator
  • Registratie: December 2001
  • Niet online

elevator

Officieel moto fan :)

Wat Infinitive zegt klopt idd - wil je groter, zal je in jouw geval naar een Longint moeten gaan :)

Verwijderd

idd, longint of eventueel reals gebruiken.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-08 00:10
Je hebt behalve de 16-bits Integer's ook 32-bits LongInt's. Daar kun je maximaal 231-1 (2147483647) instoppen dus daar zou je wel even mee vooruit moeten kunnen.

edit:
Jullie zijn allemaal veel te snel! :( ;)
Infinitive schreef op 22 november 2003 @ 15:13:
Het lijkt er sterk op dat je een 16-bits signed integer gebruikt. Dat betekent 15 bits voor het getal en 1 bit voor het teken.
Dat is niet helemaal hoe het werkt. De getallen worden opgeslagen in two's-complement notatie, waardoor de processor gewoon met negatieve getallen kan rekenen alsof het positieve getallen waren. Als 1 wordt gerepresenteerd als 00000000000000012 dan wordt -1 gerepresenteerd als 11111111111111112 en niet als 10000000000000012 zoals je misschien zou verwachten.

[ Voor 68% gewijzigd door Soultaker op 22-11-2003 15:19 ]


  • maratropa
  • Registratie: Maart 2000
  • Niet online
daar ga ik eens naar kijken thanx voor de snelle replies.

Alleen wat maui71 zegt, reals kan toch niet in zon FOR DO loop?

Ik was trouwens vergeten te zeggen

hij zegt Error 76; Constant out of range, maar het is wel duidelijk denk ik zo.

cavorka, gegroet! jouw page ken ik wel trouwens :)

specs


  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 10-08 15:15
... SoulTaker schrijft over two-complementnotatie ...
Ik weet hoe dat zit hoor ;)
Om de relatie van het limiet dat de topic-starter merkte en zijn variable duidelijk te maken heb ik voor de simpelheid maar gesteld dat je 1 teken bit hebt en 15 getal-bits. Voor de positieve waarden is dit model consistent met two-complement. :)

Op zo'n webpagina die ik zojuist bekeek stond dat een Integer het aantal bits kiest dat standaard is voor de pc/compiler (whatever). Zou voor een hedendaagse machine dit dus niet al standaard 32 bits zijn? Of is die compiler zo oud?

[ Voor 27% gewijzigd door Infinitive op 22-11-2003 16:06 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 14:22

Tomatoman

Fulltime prutser

Je hebt best kans dat het programma probleemloos compileert in Borland Delphi. Delphi maakt er dan een 32-bits console-applicatie voor Windows van. Aangezien het type 'Integer' qua omvang afhankelijk is van de compilerversie (16 bits in Turbo Pascal, 32 bits in Delphi), heb je de kans dat je geen letter hoeft te veranderen in je programma om van alle integers een 32-bits getal te maken. Compileren, klaar :).

N.B. 1
Delphi werkt met de taal Object Pascal, de objectgeoriënteerde versie van Pascal. Veel oude Turbo Pascal programma's die geen gebruik maken van specifieke DOS-commando's kunnen met heel weinig (of geen) werk worden gehercompileerd in Delphi.

N.B. 2
Van Delphi is een Personal-versie verkrijgbaar. Delphi 6 Personal is een tijdlang gratis te downloaden geweest bij Borland, dus misschien weet je hem nog ergens - legaal - vandaan te toveren. Er zijn ook heel goedkope studentenlicenties.

N.B. 3
console-applicatie <> MS-DOS

Een goede grap mag vrienden kosten.


  • maratropa
  • Registratie: Maart 2000
  • Niet online
Bedankt tomatoman, want nu word er inderdaad gewoon in dos gewerkt, ik zal er naar kijken.

Maar longint doet volgens mij goed zijn ding iig.

Om mijn korte aanwezigheid in dit forum nog verder uit te buiten;

Stel ik wil dit programma, want niet meer is dan een hele, hele zooi formules en dooromheen wat vragen voor user input, en een grafische initialisatie die met simpele "putpixel" commandos pixels in een grafiekje zet, om wil zetten naar een ander programeer programma, in windows, en zo simpel mogenlijk, waar zou ik dan verder nog naar kunnen kijken. Delphi blijkt dus misschien een goed alternatief te zijn, maar verder?

Nu werken we in dos met maar 640 maal 480 pixels, en al is het voldoende, een dubbele resolutie zou bijv. heel fijn zijn.

specs


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 14:22

Tomatoman

Fulltime prutser

Een Windowsprogramma met een 'echte' Windows-interface (dus geen console) werkt met gebeurtenissen. Zo'n gebeurtenis kan bijvoorbeeld zijn dat iemand op een knop drukt. Aan die knop hang je dan een procedure die wordt uitgevoerd telkens als er op die knop wordt gedrukt. Je programma komt daardoor wat anders in elkaar te zitten dan een good old console-applicatie, want de volgorde waarin de dingen gebeuren ligt niet meer volledig vast.

Datzelfde geldt voor het tekenen van objecten. Zo'n knoop 'weet' hoe hij zichzelf moet tekenen. Telkens als hij een Paint-commando ontvangt, tekent hij zichzelf opnieuw op het scherm. Die Paint-commando's kun je zelf in de programmacode geven, maar ze kunnen ook door het Windows-besturingssysteem worden verstuurd, bijvoorbeeld wanneer de venstergrootte wordt aangepast.

Bij jouw grafiek betekent dat, dat hij misschien maar 1 keer of misschien wel 1000 keer op het scherm moet worden getekend, je weet het nooit van tevoren. Daar zul je met je programmastructuur rekening mee moeten houden door al het tekenwerk apart te houden van de user input.

Qua logica gaat je programma er dan als volgt uitzien:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var
  Geinitialiseerd: Boolean; // beginwaarde: False

procedure Paint; 
begin
  { deze procedure kan op willekeurige momenten worden aangeroepen,
    dus niet alleen door VraagUserInput }
  if Geinitialiseerd then
  begin
    { teken nu de grafiek op het scherm }
  end;
end;

procedure VraagUserInput;
begin
  { deze procedure wordt aangeroepen als op een knop wordt geklikt }
  { vraag om user input, bijvoorbeeld via een apart dialoogvenster }
  Geinitialiseerd := True;
  Paint;
end;
Je zult de tekenlogica dus moeten scheiden van de user input. Als het rekenwerk voor de grafieken niet de spuigaten uitloopt, kun je dat best verwerken in de tekenprocedure. Kost dat echt te veel rekentijd, dan zul je een andere oplossing moeten kiezen, bijvoorbeeld door alle grafiekpunten alvast vooruit te berekenen.

Ook het tekenwerk vraagt vaak een wat andere benadering, want je bent niet meer aan een vast schermformaat gebonden (al kun je daar wel voor kiezen als je dat wilt). Veel schermcoordinaten liggen daardoor niet meer vast, maar zijn afhankelijk van de venstergrootte. Als je een verticale lijn wilt tekenen op het midden van het scherm, is de schermcoordinaat daardoor zoiets als (Schermbreedte / 2). Je zult dus veel meer met relatieve coordinaten moeten werken. De aanpak om de afzonderlijke pixels op het scherm te tekenen is in Windows-applicaties daardoor meestal niet de handigste.

Ondanks dat het lijkt dat je door deze verschillen met een console-applicatie enorm veel werk voor je kiezen krijgt, zul je merken dat je vaak juist veel minder code hoeft te schrijven om hetzelfde te bereiken. Dat komt doordat heleboel functionaliteit al standaard aanwezig is. Zo zijn er heleboel kant en klare componenten die prachtige grafieken kunnen tekenen. Wat zo'n ding moet tekenen moet je natuurlijk zelf aangeven (bijvoorbeeld met een functie die de afzonderlijke grafiekpunten berekent), maar om zaken zoals het tekenen van assenstelsels en dergelijke hoef je je niet meer druk te maken. Dat is gewoon standaardfunctionaliteit in zo'n component.

Het eenmalig ombouwen van een console-applicatie naar een gelikte Windows-interface vergt meestal nogal wat werk, want vaak ben je het beste af door de hele applicatie opnieuw te schrijven. Is dat eenmaal gebeurd, dan is het programma echter veel beter onderhoudbaar en natuurlijk veeeel mooier :).

Een goede grap mag vrienden kosten.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 14:22

Tomatoman

Fulltime prutser

Om je een idee te geven hoe het in Delphi werkt:
  1. Start Delphi.
  2. Kies File, New Application. Je hebt nu een kant een klare applicatie met daarin alle standaardfunctionaliteit. Je hebt een hoofdvenster dat verder niets doet.
  3. In de werkomgeving van Delphi kun je allerlei eigenschappen van de verschillende schermonderdelen instellen en ook nieuwe besturingselementen toevoegen. Verander de naam van het hoofdvenster naar 'DemoForm' en de caption (de venstertitel) naar 'Voorbeeldje'.
  4. Zet een TChart control op het venster en klooi wat met de eigenschappen.
  5. Zet een TButton op het vensten. Name: 'WaardenButton'. Caption: 'Waarden toevoegen'.
  6. Dubbelklik op de button. Er wordt in het codevenster een automatisch procedure gemaakt die wordt uitgevoerd als je in de applicatie op de button klikt.
  7. Voeg de volgende code toe in die procedure:
    Delphi:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    procedure TDemoForm.WaardenButtonClick(Sender: TObject);
    var
      i: Integer;
    begin
      { 10 grafiekpunten toevoegen }
      for i := 1 to 10 do
        Series1.AddXY(i, 100/ i);
      { button uitschakelen, want er mag mogen 1x grafiekpunten worden
        toegevoegd }
      WaardenButton.Enabled := False;
    end;
  8. Druk op de Run-knop in Delphi. De applicatie wordt gecompileerd en gestart.
Dat is alles! Als je nu in de applicatie op de button drukt, ziet het resultaat er als volgt uit:

Afbeeldingslocatie: http://home.planet.nl/~gerre120/linked/chart-voorbeeldje.gif

Als je het venster uitrekt, wordt de grafiek ook keurig uitgerekt. Om het tekenen van de grafiek op het scherm hoef je je geen zorgen te maken, want dat doet de chart zelf automatisch. Toch leuk hè, dat programmeren in Windows :)

Een goede grap mag vrienden kosten.


  • Cavorka
  • Registratie: April 2003
  • Laatst online: 27-03-2018

Cavorka

Internet Entrepreneur

tomatoman schreef op 22 november 2003 @ 19:54:
Toch leuk hè, dat programmeren in Windows :)
Gadver de gadverdamme.

Dit is echt te erg, ik haat DELPHI, dit kan niet, dit is TE makkelijk! Lol.

;) Thanks voor de 'tutorial' tomatoman, nu ik dit zo zie wil ik opeens Delphi leren, dit pwnt.

[ Voor 3% gewijzigd door Cavorka op 22-11-2003 20:04 ]

the-blueprints.com - The largest free blueprint collection on the internet: 50000+ drawings.


  • maratropa
  • Registratie: Maart 2000
  • Niet online
wauw tomatoman, je gaat "all out", heel erg bedankt, ik kan nooit meer in een tomaat snijden zonder dubbele gevoelens.

Ik zal nog even wat meer info geven over hoe het nu is.

Het begon ooit klein, tenminste redelijk klein en overzichtelijk, maar er werd steeds meer toegevoegd.

Ik denk (heb het nu even niet voor me hier) dat het nu zo'n 50-75 variabelen zijn, en 75-100 regels met formules, die elke keer als de loop doorlopen wordt berekend moeten worden. De bedoeling is dat er zo'n 300.000 keer de loop doorlopen moet worden, (for VAR = 1 to 300.000 do). Vanmiddag, toen ik dus via dit topic aan "longint" kwam hebben we even getest met ongeveer 120.000 keer de loop doorlopen, en dat duurde ongeveer 3 minuten op mijn pa's pentium II 400.

Dus idealiter zou ik dit progje gewoon op een wat snellere pc in windows willen draaien. Gelukkig is mijn pa ook niet zo snel met pc's en vind hij even wachten niet erg :) Maar zelf zou ik die teringzooi nog eens mooi willen maken.

Zoals je dit net uitlegde is delphi voor mij, een leek, beswel te begrijpen. De syntax lijkt ook nog wel een beetje op turbo pascal. merci.

specs

Pagina: 1