Minus/fi
English · Français · Suomi · Русский
-
ASCII:ssa joka on merkistön koodina desimaalisena 45 (tai heksadesimaalisena 2D) on määritelty - (miinusmerkiksi).
Esiintyminen
Symboli - (jota sanotaan “miinusmerkiksi”) käytetään
- ilmaisemaan että luku on negatiivinen
- vähentämään kaksi lukua
- muodostavat kahden joukon erotuksen
program minusDemo(input, output, stderr);
var
x: longint;
g: longint;
m: set of (foo, bar);
begin
// yksi operaattori: negatiivinen etumerkki
x := -42; // x saa arvokseen negatiivisen 42
// kaksi operaattoria: lukujen erotus
g := 144 - 169; // g saa arvokseen negatiivisen 25
// kaksi operaattoria: joukkojen ero
m := [foo, bar] - [bar]; // joukko m saa arvokseen joukon {foo}
end.Toiminta lukujen kanssa
Varoitus: Vähentämisen tulos (ja etumerkki muunnokset) pitäisi tehdä etumerkillisillä kokonaisluvuilla. Jos se ei ole, {$rangechecks} on otettu käyttöön, se saattaa aiheuttaa ajon aikaisen virheen. Kaikissa muissa tapauksissa syntyy aritmeettisesti virheellinen tulos.
program faultySubtraction(input, output, stderr);
var
x, y: longword;
begin
y := 1;
{$push}
{$rangechecks off} // otherwise the next expression
x := 0 - y; // yields RTE 201
{$pop}
writeLn(x);
end.Tämä ohjelma tulostaa 4294967295, mikä on sama kuin high(longword) koska tapahtuu (etumerkittömän) kokonaisluvun ylivuoto.
On kuitenkin tilanteista, joissa negatiiviset merkit eivät välttämättä aiheuta virheitä. Yritetään "negatiivisen" nollan tallentaminen ei vahingoita:
program minusOperations(input, output, stderr);
{$rangeChecks on}
var
n: longword;
begin
// "Negatiivinen" nolla
n := 0;
n := -n;Huomaa myös, että aritmeettinen kokonaisluku operaatio on suoritettu prosessorin natiivilla kokonaislukutyypillä. Vaikka välitulokset eivät ole alueella, {$rangechecks on} tuottaman koodin ansiosta tyypin rajat eivät ylity tuloksen tallentamisen jälkeen.
// välitulokset voivat olla alueen ulkopuolella:
n := 1;
n := n - n - n + 1;
end.Tämä koko ohjelma päättyy poistumiskoodilla exitCode nolla (tämä tarkoittaa "onnistunutta" ohjelman lopettamista [todellinen arvo saattaa vaihdella eri alustoilla]).
Tämän jälkimmäisen käyttäytymisen seurauksena: Prosessorin alkuperäisluvun kokonaislukujen ylivuotoa ei voida pitää kiinni (tällä tavalla). Assemblerissa on pääsy arvioimaan useita tilamerkkejä, mutta Pascalissa ei ole. Sen sijaan voidaan käyttää {$overflowChecks} -toimintoa, joka herättää ajon aikaisen virheen.
program overflowChecksDemo(input, output, stderr);
{$overflowChecks on}
var
n: {$ifdef CPU64} int64 {$else} longint {$endif};
begin
n := high(n);
n := n + 1; // Aiheuttaa ajonaikaisen virheen (RTE) 215
end.Kääntäjän ohjeella {$overflowChecks} tuotettu koodi on tehokkain , koska se käyttää suoraan saatavilla olevia status flag -arviointiohjeita (esim. "Hyppää jos ylivuoto tapahtui"). Haittapuolena, kerran käynnistetty RTE lopettaa ohjelman väistämättä. Jos tätä pidetään hyvänä, niin on tunnistettava tilanteet, jotka johtavat ylivuotoihin omalla tavalla:
program overflowAnticipation(input, output, stderr);
var
n: {$ifdef CPU64} int64 {$else} longint {$endif};
begin
// untreated
n := high(n);
n := n + 1;
writeLn(n); // prints low(n)
// anticipated: reverse operation and comparison w/ 1st operand
n := high(n);
if high(n) - 1 < n then
begin
halt(1);
end;
n := n + 1;
writeLn(n);
end.Tämä ei tietenkään ole yhtä tehokasta kuin ylivuotorekisterin testaaminen, ja täällä, ilman uudelleenkäytettyä vakiota (constant), on jopa alttiita ohjelmointivirheille (harkitse tilannetta, joka muuttaa vain yhden summan).
From the Free Pascal wiki, page "Minus/fi", as it stood on 2022-08-06 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.