Chapter 15 : Numbers and Equations
I always saw this and the tables and lists chapters as being the most straightforward: here is a niche topic that you will either not use at all or will need to know everything about all at once.
15.1 is How do we measure things?
This section just mentions that usually exact numbers aren’t super useful in fiction and that when they are, units are useful.
You can make up new kinds of numbers with units like this:
A distance is a kind of value. 5 miles specifies a distance.
There are two built-in numerical values: number
and real number
.
Section 15.2 is Numbers and Real Numbers. This is basically like ints and floats, except that the max size of a ‘number’ in z-machine is 32767, while the max number size for Glulx is 2147483647.
These are pretty low numbers compared to most programming languages, but if you have a game that is using calculations of numbers higher than 2 billion, you’re either Mike Spivey or lost in the woods.
(actually here’s Mike Spivey’s comment on this in his Junior Arithmancer postmortem):
While running my own tests on the game I ran into a problem I hadn’t anticipated. Glulx has a maximum integer capacity of just over 2 billion, and you can combine the spells in ways that will generate numbers larger than that. This was going to ruin the player’s sense of immersion in the game! I was really frustrated and disappointed for about ten minutes, until I remembered the improv motto of “Yes, and…” O.K., let’s just make the integer overflow a feature of the game and write a puzzle where you have to contend with it. (Andrew Schultz later called this a “fun evil” puzzle during testing. I’m good with that.)
Real numbers are truncated to between 6 and 9 decimal places.
showme 1.2345654321;
showme 1.2345667890;
produces
real number: 1.23457
real number: 1.23457
Inform does support scientific notation (I didn’t know this!):
let Avogadro's number be 6.022141 x 10^23;
Inform also recognizes pi
and e
as real numbers, in lowercase.
If Inform has the Use engineering notation option set, you can write things this way:
6.022141E+23;
I’m trying to think of games that could use these math abilities…I guess the recent Jigsaw let’s play showed how trigonometry is useful…
Example 253 is Alias, about american phone numbers. It uses some tricks we haven’t been taught yet:
A telephone is a kind of thing. Understand "phone" or "telephone" as a telephone.
A phone number is a kind of value. 999-9999 specifies a phone number.
Understand "Stephen" as 555-2513 when the blue paper is examined.
Test me with "dial 555-9999 / call home on the telephone / phone the president / call stephen / open drawer / read paper / call stephen / put phone in drawer / close drawer / call stephen".
Section 15.3 is Real number conversions. It mentions that it’s just here for technical reasons and is not useful for most people.
If a number is expected to be a real number (i.e. a decimal) and a number (i.e. an integer) is used, it’s converted to a decimal.
So cosine of 2
is redirected to cosine of 2.0
.
‘divided by’ will find only the whole-number quotient if just numbers are used, and the decimal approximation if any of the numbers involved is real:
3 divided by 2 = 1
3 divided by 2.0 = 1.5
3.0 divided by 2 = 1.5
3.0 divided by 2.0 = 1.5
To round real numbers to whole numbers:
1.4 to the nearest whole number = 1
1.6 to the nearest whole number = 2
-1.6 to the nearest whole number = -2
Sometimes the ‘nearest number’ is just the max number:
6 x 10^23 to the nearest whole number = 2147483647
since we literally can’t go any higher.
Inform also supports infinity:
plus infinity, minus infinity
So showme 1.0 divided by 0.0
is plus infinity
, but showme 1 divided by 0
gives a runtime error.
Also instead of runtime errors with real numbers inform will produce a ‘nonexistent real number’ for things like the square root of a negative or logarithm of a negative. It’s the equivalent of NaN.
Section 15.4 is Printing real numbers
We can print to a certain decimal place:
"The semicircle is roughly [pi to 3 decimal places] paces around."
"[1.23457 x 10^8 in decimal notation]"
(the latter prevents inform from using scientific notation)
These can be combined:
"[ (real number) to (number) decimal places in decimal notation]
Or you can just pick scientific notation:
"[the reciprocal of 137 in scientific notation]"
and finally:
say "[(real number) to (number) decimal places in scientific notation]".
Section 15.5 is Arithmetic:
We can do addition with either + or plus, and it respects units:
200 + 1 = 201
10:04 AM + two minutes = 10:06 AM
200 plus 1 = 201
minus:
200 - 1 = 199
10:04 AM - two minutes = 10:02 AM
200 minus 1 = 199
times:
201 times 3 = 603
two minutes times 4 = eight minutes
201 multiplied by 3 = 603
201 * 3 = 603
divided by (which does either the quotient for whole numbers of long division for real numbers):
201 divided by 3 = 67
201 / 3 = 67
202 divided by 3 = 67
202.0 divided by 3 = 67.33334
twenty minutes divided by 4 = five minutes
twenty minutes divided by five minutes = 4
you can divide by 0 in real numbers (getting plus infinity or minus infinity) but not whole numbers.
For modular arithmetic:
remainder after dividing 201 by 5 = 1
remainder after dividing twenty minutes by 7 = six minutes
We can either use symbols or spell out the words for operations
(If we do use the symbols, then spaces around them are obligatory: to Inform, they are words which just happen to be spelt with symbols instead of letters.)
We can round to any granularity:
201 to the nearest 5 = 200
205 to the nearest 10 = 210
10:27 AM to the nearest five minutes = 10:25 AM
We can do approximate square roots, which are slow in z-machine:
square root of 16 = 4
(always gives whole number)
real square root of 2 = 1.41421
cube root of 27 = 3
‘real cube root’ is not supported.
This next part is one where I’ve been tripped up; we can’t use the equal sign for comparisons!
We can type out or use symbols for inequalities:
if the score is less than 10
if the score < 10
if the score is at least 10
if the score >= 10
But we cannot write if the score = 10
, we have to write if the score is 10
, which is a little goofy but what can you do.
Section 15.6 is Powers and logarithms
First is rounding up:
ceiling of pi = 4.0
ceiling of -16.315 = -16.0
Next is rounding down:
floor of pi = 3.0
floor of -16.315 = -17.0
Next is absolute value:
absolute value of 62.1 = 62.1
absolute value of 0 = 0.0
absolute value of -62.1 = 62.1
absolute value of minus infinity = plus infinity
and reciprocals:
reciprocal of -2 = -0.5
reciprocal of 0.1 = 10.0
reciprocal of 7 = 0.14286
reciprocal of plus infinity = 0.0
(which is nice since 1 / 2 would just give 0)
Now there are powers:
2 to the power 4 = 16.0
100 to the power 0.5 = 10.0
7 to the power -1 = 0.14286
pi to the power 0 = 1.0
In the words of the Glulx specification document (section 2.12), “the special cases are breathtaking”: if you need to know exactly what, say, “minus infinity to the power Y” will do for different cases of Y, refer to the details of the “pow” opcode.
For square roots, don’t do 0.5 power, but for other roots, you can type:
X to the power (reciprocal of N)
For a base of e, we can say ‘exponential of’, which is presumably faster is it probably uses the maclaurin series instead of first plugging in e into the other power equation:
exponential of 0 = 1.0
exponential of 1 = e = 2.7182818
exponential of -10 = 4.53999 x 10^-5
exponential of 10 = 22026.46484
exponential of logarithm of 7.12 = 7.12
(I was teaching students the Maclaurin series for e^x just today!)
Logarithms are like so (man, why are you doing logarithms in an inform game):
logarithm to base 10 of 1000000 = 6.0
logarithm to base 10 of 350 = 2.54407
logarithm to base 2 of 256 = 8.0
and for base e (logarithm and natural logarithm mean the same thing):
logarithm of e = 1.0
natural logarithm of e = 1.0
logarithm of 1 = 0.0
logarithm of 1000 = 6.90776
logarithm of exponential of 7.12 = 7.12
Section 15.7 is Trigonometry.
Inform naturally uses radians (I’m guessing again due to Maclaurin series), but if you want sine and cosine to use degrees, just say so.
Here are some trig examples:
sine of 0 = 0
sine of 45 degrees = 0.70711
sine of (pi divided by 4) = 0.70711
sine of (pi divided by 2) = 1.0
sine of pi = 0
cosine of 0 = 1.0
cosine of 45 degrees = 0.70711
cosine of (pi divided by 4) = 0.70711
cosine of (pi divided by 2) = 0.0
cosine of pi = -1.0
tangent of 0 = 0.0
tangent of 45 degrees = 1.0
tangent of (pi divided by 4) = 1.0
tangent of (pi divided by 2) = plus infinity
(technically the last one should be plus infinity from the left and negative infinity from the right but man if you’re doing tangent of (pi divided by 2) in an actual Inform game the heavens have abandoned you anyway and you must bear your curse alone.
We also can do arcsine, arccosine, arctangent, hyperbolic sine, hyperbolic cosine, hyperbolic tangent, hyperbolic arcsine, hyperbolic arccosine (come on now Mr. Nelson, this is going too far), and hyperbolic arctangent.
Section 15.8 is units:
To assign a number to a person you can say:
A person has a number called height.
Inform claims this is dumb, as then you’d have to say Isabella has height 68
(which is exactly what I did with my rockclimbing rocks).
Instead, Inform wants you to be able to write ‘Isabella is 5 foot 8’ and have it understood.
We begin this by saying something like:
A weight is a kind of value. 10kg specifies a weight.
This is different from other kinds of values, where we explicitly listed all of the possibilities:
A colour is a kind of value. The colours are red, green and blue.
This is basically the separation between categorical and numerical data in stats.
The ‘10’ in ‘10 kg’ isn’t really important, it’s just showing inform what a typical weight might look like. So after that line you can say stuff like this:
The maximum load is a weight that varies. The maximum load is 8000kg.
if the maximum load is greater than 8000kg, ...
And inform doesn’t let numbers of different unit types mix.
You can now use the numerical values like numbers, except that units will print:
For instance, we can write:
The Weighbridge is a room. "A sign declares that the maximum load is [maximum load]."
…which will produce the text “A sign declares that the maximum load is 8000kg.”
The default is whole numbers only.
If you want a real number, type this kind of thing:
1.0 kg specifies a weight.
For whole number specifications, we can only use positive numbers. If you want negatives, say this:
-10 kg specifies a weight.
Time for examples!
Exampe 254 is rBGH:
A counter, a one-way mirror, and a stool are scenery in the Facility. The stool is an enterable supporter. The counter supports a plate.
Height is a kind of value. 5 feet 11 inches specifies a height. 5'11 specifies a height. A person has a height.
Definition: a person is tall if its height is 6 feet 0 inches or more.
Definition: a person is short if its height is 5 feet 4 inches or less.
When play begins:
now the height of the player is a random height between 5 feet 2 inches and 6 feet 4 inches;
now the right hand status line is "[height of player]".
Instead of examining the player:
say "You, Test Subject, are [height of the player] tall."
The growth pill is a kind of thing. A growth pill is always edible. The description is usually "It is leaf-green and has a reassuring logo of a curling vine on the side. Nothing to worry about, nothing at all." Two growth pills are on the plate.
After eating the growth pill:
increase the height of the player by 0 feet 6 inches;
say "Your spine does something frightening and painful, and you find yourself looking down on the room from a wholly new angle.";
try looking.
Example 255 is Lethal concentration 1:
This is a very complex example, which reminds me of an old XYZZY nominee called Oxygen (or something). I can’t copy everything, but here’s the idea:
A concentration is a kind of value. 200.9ppm specifies concentration. 200.9 ppm specifies concentration.
A room has a concentration called current concentration. A room has a concentration called former concentration.
Probability inverse is a number that varies. [This is expressed as an inverse of the actual probability of diffusion from one room to another, to avoid error.] Probability inverse is 20. [That is, any given molecule of gas has a 5% chance of leaving by a given doorway at any given minute. Probability inverse should never drop below 10, the maximum number of exits from the room.]
A diffusion rule (this is the gas movement rule):
repeat with space running through rooms:
let sum be 0.0 ppm;
repeat with way running through directions:
let second space be the room way from the space;
if second space is a room:
let difference be the former concentration of the second space minus the former concentration of the space;
increase sum by the difference;
let sum be sum divided by probability inverse;
now current concentration of the space is the former concentration of the space plus the sum.
This kind of diffusion is exactly how amenability is studied in geometric group theory, and my advisor did this stuff a lot.
This example also gives a text map of the whole game with concentrations marked, and has gas sources and sinks, etc. Pretty wild!
Example 256 is Wonderland
An altitude is a kind of value. 1000 feet specifies an altitude. A room has an altitude.
Definition: a room is low if its altitude is 3000 feet or less. Definition: a room is high if its altitude is 5000 feet or more.
Instead of going down:
if an adjacent room is lower than the location:
let the valley be the lowest adjacent room;
let the way be the best route from the location to the valley;
say "(that is, [way])[paragraph break]";
try going the way;
otherwise:
say "You're in a local valley: there's no down from here."
Instead of going up:
if an adjacent room is higher than the location:
let the peak be the highest adjacent room;
let the way be the best route from the location to the peak;
say "(that is, [way])[paragraph break]";
try going the way;
otherwise:
say "You're on a local peak."
Example 257 is Lethal Concentration 2
This makes gas more likely to sink down than up:
To decide what number is the probability inverse between (space - a room) and (second space - a room):
let guess be 20;
let way be the best route from space to second space;
if way is up, let guess be 50;
if way is down, let guess be 10;
if the guess is less than 10, decide on 10;
decide on guess.
Section 15.9 is Multiple notations
You can have mutliple units for a weight, including versions with spaces or multiple words:
A weight is a kind of value. 10kg specifies a weight. 10kg net specifies a weight. 10 kg specifies a weight.
You can also scale units:
1 tonne specifies a weight scaled up by 1000.
You can specify singular and plural:
1 tonne (singular) specifies a weight scaled up by 1000.
2 tonnes (plural) specifies a weight scaled up by 1000.
Which of the 3 version of kg will inform print? I will find out.
Hmmm, I made a value using ‘10kg net’ and it printed as ‘10kg’, so I assume it prints with the first format you use.
Section 15.10 is Scaling and equivalents
If you use whole numbers in your original definition, inform will require you to use whole numbers all along.
So if you say 1 kg specifies a weight
, you can’t have fractions.
But… you can scale things up and down.
A length is a kind of value. 1m specifies a length.
1km specifies a length scaled up by 1000.
1cm specifies a length scaled down by 100.
So you can type 3cm, 0.03m, and 0.00003km all mean the same thing, and inform starts using decimals.
Inform takes the smallest ‘scale’ and lets that go up to the max number (around 2 billion for glulx), so if you scale things by 2 billion, the largest scale can only go up to 2!
You can pick the scaling yourself like this:
A length is a kind of value. 1m specifies a length scaled at 10000.
, and inform will only let meters go up to about 2 hundred thousand, and can be specified to 4 decimal places.
You can also make unit conversions:
1 mile specifies a length equivalent to 1609m.
Section 15.11 is Named notations:
Let’s say we write this:
A weight is a kind of value. 10kg specifies a weight.
1 tonne (singular) specifies a weight scaled up by 1000.
2 tonnes (plural) specifies a weight scaled up by 1000.
Then inform prints it like this:
45kg -> "45kg"
1000kg -> "1 tonne"
2500kg -> "2.5 tonnes"
80000kg -> "80 tonnes"
So it automatically converts to convenient units (the documentation says it is minimising the integer part of the unit, but trying to keep it non-zero. So Inform prefers "45kg" to "0.045 tonnes".
).
If you want to force it to be printed a certain way, you can name your notation (in this example, it’s the part after the comma in the parentheses):
1 tonne (singular, in tonnes) specifies a weight scaled up by 1000.
2 tonnes (plural, in tonnes) specifies a weight scaled up by 1000.
and then can use it like this:
"The weighbridge warns you not to exceed [the maximum load in tonnes]."
Section 5.12 is Making the verb ‘to weigh’
This is really useful and I had to get help from many people when making rockclimbing to do what this section is saying (although the tile of this section is a bit misleading).
Basically you can create a verb for a value:
Weight is a kind of value. 1kg specifies a weight. Every thing has a weight.
The verb to weigh means the weight property.
A thing usually weighs 1kg. The lead pig weighs 45kg.
What makes this exceptionally useful is that you can now use this verb in descriptions for finding lists, random things, and conditions.
Example 258 is Dimensions:
A length is a kind of value. 10m specifies a length. An area is a kind of value. 10 sq m specifies an area. A length times a length specifies an area.
Hmm, this is something entirely new: a length time a length specifies an area. Wild!
A weight is a kind of value. 10kg specifies a weight. Everything has a weight.
The verb to weigh means the weight property. A thing usually weighs 1kg.
Definition: A thing is light if its weight is 3kg or less.
Definition: A thing is heavy if its weight is 10kg or more.
The balance platform is a supporter in the Weighbridge. "The balance platform is 10m by 8m, giving it an area of [10m multiplied by 8m], currently weighing [the list of things on the platform]. The scale alongside reads: [total weight of things on the platform]. [if two things are on the platform]Average weight is: [the total weight of things on the platform divided by the number of things on the platform]. Heaviest item is [the heaviest thing on the platform], at [weight of the heaviest thing on the platform]. Lightest item is [the lightest thing on the platform], at [weight of the lightest thing on the platform].[otherwise]It seems to be able to weigh several things at once."
Example 259 is Lead Cuts Paper
A weight is a kind of value. 10kg specifies a weight. Everything has a weight. A thing usually has weight 1kg.
A container has a weight called breaking strain. The breaking strain of a container is usually 50kg. Definition: A container is bursting if the total weight of things in it is greater than its breaking strain.
A lead pig, a feather, a silver coin and a paper bag are in a room called the Metallurgy Workshop. The paper bag is a container with breaking strain 2kg. The lead pig has weight 50kg.
Every turn when a container (called the sack) held by someone visible (called the chump) is bursting:
say "[The sack] splits and breaks under the weight! [if the player is the chump]You discard[otherwise][The chump] discards[end if] its ruined remains, looking miserably down at [the list of things in the sack] on the floor.";
now all of the things in the sack are in the location;
now the sack is nowhere.
Sectoin 15.13 is The Metric Units Extension.
If you want tons of units and specifications, there are built in extensions:
(a) The built-in extension “Metric Units by Graham Nelson” sets up a whole range of scientific units, with all the notations we are likely to want. Real numbers are used throughout, so large and small-scale calculations can be carried out quite accurately. Like the other built-in extensions, it has its own documentation and examples.
(b) The built-in extension “Approximate Metric Units by Graham Nelson” does the same but using whole numbers, scaled about right for human situations. This won’t be much use for extensive calculations, and won’t be as accurate, but it will work reasonably well if real arithmetic isn’t available.
Absent from all of this chapter is how to make Inform print commas every 3 digits, which someone in chat was asking about. It turns out to be pretty hard.
Section 15.14 is Notations including more than one number
This is like heights with feet and inches, or time with minutes and seconds.
So you can say stuff like:
A running time is a kind of value. 3'59 specifies a running time.
or
A height is a kind of value. 5 foot 11 specifies a height.
You can make up to 8 numbers in each specification.
Referring back to the ‘3’59’ example:
The choice of "3" here makes no difference, much as the choice of "10" in the weight examples was arbitrary. But the "59" is significant. Numbers after the first one are expected to range from 0 up to the value we quote - so in this case, the number of seconds can be anything from 0 to 59.
Hmm, I didn’t know that! So for parts like this you need to make something as close to ‘ticking over’ as possible. Actually, you could do binary math like this with having a specification like `1 a 1 b 1 c 1 d 1 e 1 f 1 g 1 h’.
Haha, this works great, I just tried running this:
A binary number is a kind of value. 1 a 1 b 1 c 1 d 1 e 1 f 1 g 1 specifies a binary number.
baseCounter is always 0 a 0 b 0 c 0 d 0 e 0 f 0 g 1.
Counter is a binary number that varies. Counter is 0 a 0 b 0 c 0 d 0 e 0 f 0 g 1.
Every turn:
say counter;
now counter is counter plus basecounter;
This just counts up in binary! Although now I realize I didn’t need to use letters, I could have just used apostrophes.
Only the first number in something like this can be negative, and only if you specify negative in the original:
A secret sign is a kind of value. -2x17 specifies a secret sign with parts mystery and enigma.
Notations can’t have double quotes (even though arcs have them) but other punctuation is okay between digits:
A monetary value is a kind of value. $1.99 specifies a monetary value.
An aspect ratio is a kind of value. 16:9 specifies an aspect ratio.
Section 15.15 is the parts of a number specification. It lets you name the different chunks of a number:
A monetary value is a kind of value. $1.99 specifies a monetary value with parts dollars and cents.
We can now find the relevant parts like so. Suppose that “sum” is a monetary value. Then:
dollars part of sum
cents part of sum
are both numbers, so for instance we can
say "Looks like around [dollars part of sum in words] dollar[s]."
We can also go the other way:
monetary value with dollars part 4 cents part 72
produces the monetary value $4.72. (Note the lack of commas or "and"s, and that the parts have to be given in the right order.)
Naming parts of numbers lets you add other stuff onto it:
A monetary value is a kind of value. $1.99 specifies a monetary value with parts dollars and cents (optional, preamble optional).
This lets you type dollars without cents (optional), and omitting the decimal (preamble optional). Note that both options apply to cents since they are right next to cents. Apparently you can’t make the first part optional though (dollars), as I just tried doing that.
The other option is 'without leading zeroes", used when one of the parts is specified as multiple digits but we might not want that:
An aspect ratio is a kind of value. 16:20 specifies an aspect ratio with parts width and height (without leading zeros).
This ensures that when the ratio 4:3 is printed, it will be printed as “4:3” and not “4:03” as would otherwise happen.
Example 260 is Zqlran Era 8.
A Zqlran date is a kind of value. 14-88 specifies a Zqlran date with parts zqls and frbs. Current zqlran date is a zqlran date that varies. The current zqlran date is 8-22. Previous zqlran date is a zqlran date that varies. The previous zqlran date is 8-20.
The Zqlran time rule is listed instead of the advance time rule in the turn sequence rules.
This is the Zqlran time rule:
increment turn count;
now the previous zqlran date is current zqlran date;
increase the current zqlran date by 0-02;
repeat through the Table of Zql Schedule:
if era entry is greater than previous zqlran date and era entry is not greater than current zqlran date:
say event entry;
say paragraph break;
blank out the whole row.
Section 15.16 is Understanding specified numbers:
You can just throw values that are specified numbers into ‘understand’ commands:
The Oval Office is a room. Josh and Toby are men in the Oval. A height is a kind of value. 5 foot 11 specifies a height. A person has a height. Josh is 5 foot 8. Toby is 5 foot 10.
Height guessing is an action applying to one thing and one height. Understand "guess [someone] is [height]" as height guessing.
Check height guessing: if the noun is not a person, say "You can only guess the height of people." instead. Carry out height guessing: if the height of the noun is the height understood, say "Spot on!"; if the height of the noun is greater than the height understood, say "No, [the noun] is taller than that."; if the height of the noun is less than the height understood, say "No, [the noun] is shorter than that."
Example 261 is Snip:
A string is a kind of thing. A string has a length. The length of a string is usually 36 inches.
Before printing the name of a string, say "[length] piece of ". Rule for printing the plural name of a string: say "[length] pieces of string".
Understand the command "cut" as something new. Understand "cut [length] from/off [something]" as trimming it by (with nouns reversed). Understand "cut [something] by [length]" as trimming it by. Understand the command "trim" as "cut".
Trimming it by is an action applying to one thing and one length.
This is a very complex example, but the above is a taste.
Section 15.17 is Totals:
This is just a way of adding stuff up. With some preamble:
A weight is a kind of value. 10kg specifies a weight. Everything has a weight. A thing usually has weight 1kg. A man usually has weight 80kg. A woman usually has weight 67kg.
Definition: A thing is light if its weight is 3kg or less.
Definition: A thing is heavy if its weight is 10kg or more.
we can say:
The balance platform is a supporter in the Weighbridge. "The balance platform is currently weighing [the list of things on the platform]. The scale alongside reads: [total weight of things on the platform]."
This only works because ‘everything has a weight’.
You can also use superlatives:
the weight of the heaviest thing on the platform
the weight of the lightest thing on the platform
Example 262 is Nickel and Dimed
This is a very complex example involing a monetary system using US money. It includes different coins and denominations.