-
Notifications
You must be signed in to change notification settings - Fork 4
/
sect02.html
165 lines (131 loc) · 5.63 KB
/
sect02.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<!DOCTYPE html>
<html>
<head>
<title>The Z-Machine Standards Document</title>
<link rel="stylesheet" type="text/css" href="zspec.css">
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
</head>
<body>
<img class="icon" src="images/icon02.gif" alt="">
<h1>2. Numbers and arithmetic</h1>
<hr>
<p>2.1 <a href="#2.1">Numbers</a> /
2.2 <a href="#2.2">Signed operations</a> /
2.3 <a href="#2.3">Arithmetic errors</a> /
2.4 <a href="#2.4">Random number generator</a>
</p>
<hr>
<h2 id="2.1">2.1</h2>
<p>In the Z-machine, numbers are usually stored in 2 bytes
(in the form most-significant-byte first, then least-significant)
and hold any value in the range <strong>$0000</strong> to <strong>$ffff</strong> (0 to 65535
decimal).
</p>
<h2 id="2.2">2.2</h2>
<p>These values are sometimes regarded as signed, in the range
-32768 to 32767. In effect -n is stored as 65536-n
and so the top bit is the sign bit.
</p>
<h2 id="2.2.1">2.2.1</h2>
<p>The operations of numerical comparison, multiplication,
addition, subtraction, division, remainder-after-division and
printing of numbers are signed; bitwise operations are unsigned.
(In particular, since comparison is signed, it is unsafe to compare
two addresses using simply <a href="sect15.html#jl"><strong>jl</strong></a>
and <a href="sect15.html#jg"><strong>jg</strong></a>.)
</p>
<h2 id="2.3">2.3</h2>
<p>Arithmetic errors:</p>
<h2 id="2.3.1">2.3.1</h2>
<p>It is illegal to divide by 0 (or to ask for remainder after
division by 0) and an interpreter should halt with an error message
if this occurs.
</p>
<h2 id="2.3.2">2.3.2</h2>
<p>Formally it has never been specified what the result of an
out-of-range calculation should be. The author suggests that the
result should be reduced modulo <strong>$10000</strong>.
</p>
<h2 id="2.4">2.4</h2>
<p>The Z-machine needs a random number generator which at any time
has one of two states, "random" and "predictable". When the game
starts or restarts the state becomes "random". Ideally the generator
should not produce identical sequences after each restart.
</p>
<h2 id="2.4.1">2.4.1</h2>
<p>When "random", it must be capable of generating a uniformly
random integer in the range 1 <= x <= n, for any value
1 <= n <= 32767. Any method can be used for this (for instance,
using the host computer's clock time in milliseconds). The uniformity
of randomness should be optimised for low values of n (say, up to
100 or so) and it is especially important to avoid regular patterns
appearing in remainders after division (most crudely, being alternately
odd and even).
</p>
<h2 id="2.4.2">2.4.2</h2>
<p>The generator is switched into "predictable" state with a
seed value. On any two occasions when the same seed is sown, identical
sequences of values must result (for an indefinite period) until
the generator is switched back into "random" mode. The generator
should cope well with very low seed values, such as 10, and should not
depend on the seed containing many non-zero bits.
</p>
<h2 id="2.4.3">2.4.3</h2>
<p>The interpreter is permitted to switch between these states
on request of the player. (This is useful for testing purposes.)
</p>
<hr>
<h2 id="remarks">Remarks</h2>
<p>It is dangerous to rely on the older ANSI C random number routines (rand() and srand()), as some
implementations of these are very poor. This has made some games (in
particular, 'Balances') unwinnable on some Unix ports of <strong>Zip</strong>.
</p>
<p>The author suggests the following algorithm:</p>
<p><strong>1.</strong> In "random" mode, the generator uses the host computer's
clock to obtain a random sequence of bits.</p>
<p><strong>2.</strong> In "predictable" mode, the generator should store the
seed value <em>S</em>. If <em>S</em> < 1000 it should then internally generate
</p>
<p>1, 2, 3, ..., <em>S</em>, 1, 2, 3, ..., <em>S</em>, 1, ...</p>
<p>so that <strong>random n</strong> produces the next entry in this sequence modulo n.
If <em>S</em> >= 1000 then <em>S</em> is used as a seed in a standard seeded
random-number generator.
</p>
<p>(The rising sequence is useful for testing, since it will
produce all possible values in sequence. On the other hand, a seeded
but fairly random generator is useful for testing entire scripts.)
</p>
<p>Note that version 0.2 of this standard mistakenly asserted that division
and remainder are unsigned, a myth deriving from a bug in <strong>Zip</strong>. Infocom's
interpreters do sign division (this is relied on when calculating
pizza cooking times for the microwave oven in 'The Lurking Horror'). Here
are some correct Z-machine calculations:
</p>
<pre>
-11 / 2 = -5 -11 / -2 = 5 11 / -2 = -5
-13 % 5 = -3 13 % -5 = 3 -13 % -5 = -3
</pre>
<hr>
<p>
<a href="index.html">Contents</a> /
<a href="preface.html">Preface</a> /
<a href="overview.html">Overview</a>
</p>
<p>Section
<a href="sect01.html">1</a> / <a href="sect02.html">2</a> /
<a href="sect03.html">3</a> / <a href="sect04.html">4</a> /
<a href="sect05.html">5</a> / <a href="sect06.html">6</a> /
<a href="sect07.html">7</a> / <a href="sect08.html">8</a> /
<a href="sect09.html">9</a> / <a href="sect10.html">10</a> /
<a href="sect11.html">11</a> / <a href="sect12.html">12</a> /
<a href="sect13.html">13</a> / <a href="sect14.html">14</a> /
<a href="sect15.html">15</a> / <a href="sect16.html">16</a>
</p>
<p>Appendix
<a href="appa.html">A</a> / <a href="appb.html">B</a> /
<a href="appc.html">C</a> / <a href="appd.html">D</a> /
<a href="appe.html">E</a> / <a href="appf.html">F</a>
</p>
<hr>
</body>
</html>