Difference between revisions of "Minus"

From Lazarus wiki
Jump to navigationJump to search
m (→‎occurrences: insert missing determiner)
m (Removed category included in page template)
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
{{Minus}}
 
{{Minus}}
  
<div style="float:left; margin: 0 10px 10px 0; padding:40px; font-size:500%; font-family: Georgia; background-color: #f9f9f9; border: 2px solid #777777;">-</div>
+
<div style="float:right; margin: 0 10px 10px 0; padding:40px; font-size:500%; font-family: Georgia; background-color: #f9f9f9; border: 2px solid #777777;">-</div>
  
 
In [[ASCII]], the character code decimal <syntaxhighlight lang="pascal" enclose="none">45</syntaxhighlight>  
 
In [[ASCII]], the character code decimal <syntaxhighlight lang="pascal" enclose="none">45</syntaxhighlight>  
Line 7: Line 7:
 
<syntaxhighlight lang="pascal" enclose="none">-</syntaxhighlight> (hyphen-minus).
 
<syntaxhighlight lang="pascal" enclose="none">-</syntaxhighlight> (hyphen-minus).
  
== occurrences ==
+
== Occurrences ==
  
 
The symbol <syntaxhighlight lang="pascal" enclose="none">-</syntaxhighlight> (pronounced “minus”) is used to
 
The symbol <syntaxhighlight lang="pascal" enclose="none">-</syntaxhighlight> (pronounced “minus”) is used to
Line 37: Line 37:
 
You can write such stupid expressions as <syntaxhighlight lang="pascal" enclose="none">----+--+--+--8</syntaxhighlight>.
 
You can write such stupid expressions as <syntaxhighlight lang="pascal" enclose="none">----+--+--+--8</syntaxhighlight>.
  
== operation with numbers ==
+
== Operation with numbers ==
  
 
Beware:
 
Beware:
 
The result's target of subtractions (and sign inversions) should be a ''signed'' integer.
 
The result's target of subtractions (and sign inversions) should be a ''signed'' integer.
If it's not, with [[sRangechecks|<syntaxhighlight lang="pascal" enclose="none">{$rangechecks}</syntaxhighlight>]] enabled, it will possibly cause a run-time error.
+
If it's not, with [[sRangechecks|<syntaxhighlight lang="pascal" enclose="none">{$rangechecks}</syntaxhighlight>]] [[Compiler directive|directive]] enabled, it will possibly cause a [[runtime error|run-time error]].
 
In any other case an arithmetically wrong result is produced.
 
In any other case an arithmetically wrong result is produced.
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
Line 59: Line 59:
 
end.
 
end.
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 
This program prints <syntaxhighlight lang="pascal" enclose="none">4294967295</syntaxhighlight>, which equals to <syntaxhighlight lang="pascal" enclose="none">high(longword)</syntaxhighlight> because of the (unsigned) integer overflow.
 
This program prints <syntaxhighlight lang="pascal" enclose="none">4294967295</syntaxhighlight>, which equals to <syntaxhighlight lang="pascal" enclose="none">high(longword)</syntaxhighlight> because of the (unsigned) integer overflow.
  
 
However note, there are situations where negative signs do not necessarily provoke an error.
 
However note, there are situations where negative signs do not necessarily provoke an error.
 
Attempting to store a “negative” zero won't harm:
 
Attempting to store a “negative” zero won't harm:
 +
 
<syntaxhighlight lang="pascal" line>
 
<syntaxhighlight lang="pascal" line>
 
program minusOperations(input, output, stderr);
 
program minusOperations(input, output, stderr);
Line 90: Line 92:
 
In consequence of the latter mentioned behavior:
 
In consequence of the latter mentioned behavior:
 
Integer overflows in the processor's native type can not be caught (in that way).
 
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.
+
In [[Assembly language|assembler]] you would have access evaluating several status flags, but in [[Pascal]] you do not.
 
Instead you can use [[sOverflowchecks|<syntaxhighlight lang="pascal" enclose="none">{$overflowChecks}</syntaxhighlight>]] which will evoke a run-time error.
 
Instead you can use [[sOverflowchecks|<syntaxhighlight lang="pascal" enclose="none">{$overflowChecks}</syntaxhighlight>]] which will evoke a run-time error.
  
Line 99: Line 101:
  
 
var
 
var
n: {$ifdef CPU64} int64 {$else} longint {$endif};
+
n: nativeInt;
  
 
begin
 
begin
Line 136: Line 138:
  
 
{{Symbols}}
 
{{Symbols}}
 
[[Category:Code]]
 

Revision as of 00:59, 21 February 2020

English (en) suomi (fi) français (fr) русский (ru)

-

In ASCII, the character code decimal 45 (or hexadecimal 2D) is defined to be - (hyphen-minus).

Occurrences

The symbol - (pronounced “minus”) is used to

  • indicate the negative sign of a number literal
  • subtract two numbers (using infix notation)
  • form the difference of two sets.
program minusDemo(input, output, stderr);

var
	x: longint;
	g: longint;
	m: set of (foo, bar);

begin
	// unary operator: negative sign
	x := -42;                     // x becomes negative 42
	
	// binary operator: difference of numbers
	g := 144 - 169;               // g becomes negative 25
	
	// binary operator: difference of sets
	m := [foo, bar] - [bar];      // m becomes {foo}
end.

Minus is also a unary operator. You can write such stupid expressions as ----+--+--+--8.

Operation with numbers

Beware: The result's target of subtractions (and sign inversions) should be a signed integer. If it's not, with {$rangechecks} directive enabled, it will possibly cause a run-time error. In any other case an arithmetically wrong result is produced.

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.

This program prints 4294967295, which equals to high(longword) because of the (unsigned) integer overflow.

However note, there are situations where negative signs do not necessarily provoke an error. Attempting to store a “negative” zero won't harm:

 1program minusOperations(input, output, stderr);
 2
 3{$rangeChecks on}
 4
 5var
 6	n: longword;
 7
 8begin
 9	// "negative" zero equals to (sign-less) zero
10	n := 0;
11	n := -n;

Also 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.

13	// intermediate results can be out of range:
14	n := 1;
15	n := n - n - n + 1;
16end.

This whole program will finish with an exitCode of zero (that means “successful” [actual value might vary among platforms]).

In consequence of the latter mentioned behavior: Integer overflows in the processor's native type can not be caught (in that way). In assembler you would have access evaluating several status flags, but in Pascal you do not. Instead you can use {$overflowChecks} which will evoke a run-time error.

 1program overflowChecksDemo(input, output, stderr);
 2
 3{$overflowChecks on}
 4
 5var
 6	n: nativeInt;
 7
 8begin
 9	n := high(n);
10	n := n + 1;   // will yield RTE 215
11end.

The 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:

 1program overflowAnticipation(input, output, stderr);
 2
 3var
 4	n: {$ifdef CPU64} int64 {$else} longint {$endif};
 5
 6begin
 7	// untreated
 8	n := high(n);
 9	n := n + 1;
10	writeLn(n); // prints low(n)
11	
12	// anticipated: reverse operation and comparison w/ 1st operand
13	n := high(n);
14	if high(n) - 1 < n then
15	begin
16		halt(1);
17	end;
18	n := n + 1;
19	writeLn(n);
20end.

Obviously this won't be as efficient as testing the overflow status flag, and here, without any re-used constant, is even prone to programming errors (consider the situation changing the subtrahend in one line of code only).


navigation bar: topic: Pascal symbols
single characters

+ (plus)  •  - (minus)  •  * (asterisk)  •  / (slash)
= (equal)  •  > (greater than)  •  < (less than)
. (period)  •  : (colon)  •  ; (semi colon)
^ (hat)  •  @ (at)
$ (dollar sign)  •  & (ampersand)  •  # (hash)
' (single quote)

character pairs

<> (not equal)  •  <= (less than or equal)  •  := (becomes)  •  >= (greater than or equal)

 •  >< (symmetric difference)  •  // (double slash)