Sign in Join
Wiki copytemporary

Minus: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-<div style="float:right; margin: 0 10px 10px 0; padding:40px; font-size:500%; font-family: Georgia; background-color: #f9f9f9; border: 2px solid #777777;">
2-
31\-
4-
5-</div>
62
73In [[ASCII]], the character code decimal `45` (or [[Hexadecimal|hexadecimal]] `2D`) is defined to be `-` (hyphen-minus).
84
95## Occurrences
106
117The symbol `-` (pronounced “minus”) is used to
128
139- indicate the negative sign of a number literal
1410- subtract two numbers (using infix notation)
1511- form the difference of two [[Set|sets]].
1612
1713``` pascal
1814program minusDemo(input, output, stderr);
1915
2016var
2117 x: longint;
2218 g: longint;
2319 m: set of (foo, bar);
2420
2521begin
2622 // unary operator: negative sign
2723 x := -42; // x becomes negative 42
2824
2925 // binary operator: difference of numbers
3026 g := 144 - 169; // g becomes negative 25
3127
3228 // binary operator: difference of sets
3329 m := [foo, bar] - [bar]; // m becomes {foo}
3430end.
3531```
3632
3733Minus is also a unary operator. You can write such stupid expressions as `----+--+--+--8`.
3834
3935## Operation with numbers
4036
4137Beware: The result's target of subtractions (and sign inversions) should be a *signed* integer. If it's not, with [[sRangechecks|{$rangechecks}]] [[Compiler directive|directive]] enabled, it will possibly cause a [[runtime error|run-time error]]. In any other case an arithmetically wrong result is produced.
4238
4339``` pascal
4440program faultySubtraction(input, output, stderr);
4541
4642var
4743 x, y: longword;
4844
4945begin
5046 y := 1;
5147 {$push}
5248 {$rangechecks off} // otherwise the next expression
5349 x := 0 - y; // yields RTE 201
5450 {$pop}
5551
5652 writeLn(x);
5753end.
5854```
5955
6056This program prints `4294967295`, which equals to `high(longword)` because of the (unsigned) integer overflow.
6157
6258However note, there are situations where negative signs do not necessarily provoke an error. Attempting to store a “negative” zero won't harm:
6359
6460``` pascal
6561program minusOperations(input, output, stderr);
6662
6763{$rangeChecks on}
6864
6965var
7066 n: longword;
7167
7268begin
7369 // "negative" zero equals to (sign-less) zero
7470 n := 0;
7571 n := -n;
7672```
7773
7874Also note, arithmetic integer operations are done with the processor's native integer type. Although intermediate results fall out of range, the code generated by `{$rangechecks on}` ensures the type's boundaries aren't exceeded *after* the result's already stored.
7975
8076``` pascal
8177 // intermediate results can be out of range:
8278 n := 1;
8379 n := n - n - n + 1;
8480end.
8581```
8682
8783This whole program will finish with an [`exitCode`](https://www.freepascal.org/docs-html/rtl/system/exitcode.html) of zero (that means “successful” \[actual value might vary among platforms\]).
8884
8985In consequence of the latter mentioned behavior: Integer overflows in the processor's native type can not be caught (in that way). In [[Assembly language|assembler]] you would have access evaluating several status flags, but in [[Pascal]] you do not. Instead you can use [[sOverflowchecks|{$overflowChecks}]] which will evoke a run-time error.
9086
9187``` pascal
9288program overflowChecksDemo(input, output, stderr);
9389
9490{$overflowChecks on}
9591
9692var
9793 n: nativeInt;
9894
9995begin
10096 n := high(n);
10197 n := n + 1; // will yield RTE 215
10298end.
10399```
104100
105101The generated code by the `{$overflowChecks}` directive is the *most efficient*, since it directly uses available status flag evaluation instructions (e.g. “jump if overflow occured”). On the downside, a once triggered RTE will inevitably terminate the program. If this is regarded as counter-productive, you would have to recognize situations leading to overflows on your own:
106102
107103``` pascal
108104program overflowAnticipation(input, output, stderr);
109105
110106var
111107 n: {$ifdef CPU64} int64 {$else} longint {$endif};
112108
113109begin
114110 // untreated
115111 n := high(n);
116112 n := n + 1;
117113 writeLn(n); // prints low(n)
118114
119115 // anticipated: reverse operation and comparison w/ 1st operand
120116 n := high(n);
121117 if high(n) - 1 < n then
122118 begin
123119 halt(1);
124120 end;
125121 n := n + 1;
126122 writeLn(n);
127123end.
128124```
129125
130126Obviously this won't be as efficient as testing the overflow status flag, and here, without any *re-used* [[Constant|constant]], is even prone to programming errors (consider the situation changing the subtrahend in one line of code only).
131127
132128---
133129*From the Free Pascal wiki, page "Minus", 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](/wiki-contact).*

Back to history