>>  <<  Ndx  Usr  Pri  JfC  LJ  Phr  Dic  Rel  Voc  !:  wd  Help  Learning J

Chapter 19: Numbers

The topics covered in this chapter are:

  • The different kinds of numbers available in J
  • Special numbers (infinities and indeterminates)
  • Notations for writing numbers
  • How numbers are displayed
  • Random numbers

19.1 Six Different Kinds of Numbers

J supports computation with numbers of these kinds:

  • booleans (or truth-values)
  • integers
  • real (or floating-point) numbers
  • complex numbers
  • extended integers (that is, arbitrarily large integers exactly represented)
  • rationals (that is, pairs of extended integers)

Each kind of number has its own internal representation in memory. For example, an array containing only the truth-values 0 and 1 is stored in a compact internal form, called "boolean", rather than in the floating-point form. Similarly an array containing only (relatively small) whole numbers is stored in a compact form called "integer".

The choice of appropriate representation is managed entirely automatically by the J system, and is not normally something the programmer must be aware of. However, there is a means of testing the representation of a number. Here is a utility function for the purpose.

   types =: 'bool';'int';'float';'complex';'ext int';'rational'
   
   type  =: > @: ({ & types) @: (1 4 8 16 64 128 & i.) @: (3 !: 0)
   

type 0=0 type 37 type 2.5 type 12345678901
bool int float float

19.1.1 Booleans

There are built-in functions for logical computation with boolean values. Giving conventional names to these functions:

   and    =: *.
   or     =: +.
   not    =: -.
   notand =: *: 
   notor  =: +:

we can show their truth-tables:

   p =: 4 1 $ 0 0 1 1
   q =: 4 1 $ 0 1 0 1
   

p q p and q p or q not p p notand q
0
0
1
1
0
1
0
1
0
0
0
1
0
1
1
1
1
1
0
0
1
1
1
0

Further logical functions can be defined in the usual way. For example, logical implication, with the scheme

     p implies q    means   not (p and not q)
   

is defined by not composed with the hook and not

   implies =: not @ (and not)
   

p q p implies q
0
0
1
1
0
1
0
1
1
1
0
1

We regard the booleans as numbers because they can be interpreted as having arithmetic values. To illustrate, implication has the same truth-table as less-than-or-equal:

p implies q p <: q
1
1
0
1
1
1
0
1

For another example of booleans as numbers, the sum of the positive numbers in a list is shown by:

z =: 3 _1 4 b =: z > 0 b * z +/ b * z
3 _1 4 1 0 1 3 0 4 7

19.1.2 Integers

On a 32-bit machine integers range between _2147483648 and 2147483647.

The result of arithmetic with integers is converted to floating-point if larger than the maximum integer.

maxint=:2147483647 type maxint z =: 1+maxint type z
2147483647 int 2.14748e9 float

19.1.3 Floating-Point Numbers

A floating-point number is a number represented in the computer in such a way that: (1) there may be a a fractional part as well as a whole-number part. (2) a fixed amount of computer storage is occupied by the number, whatever the value of the number. and therefore (3) the precision with which the number is represented is limited to at most about 17 significant decimal digits (on a PC).

Examples of floating-point numbers are 0.25 2.5 12345678901

We will use the term "real" more or less interchangeably with "floating-point".

19.1.4 Scientific Notation

What is sometimes called "scientific notation" is a convenient way of writing very large or very small numbers. For example, 1500000 may be written as 1.5e6, meaning 1.5 * 10^6. The general scheme is that a number written in the form XeY, where Y is a (positive or negative) integer means (X * 10^Y).

3e2 1.5e6 1.5e_4
300 1500000 0.00015

Note that in 3e2 the letter e is not any kind of function; it is part of the notation for writing numbers, just as a decimal point is part of the notation.

We say that the string of characters 3 followed by e followed by 2 is a numeral which denotes the number 300. The string of characters 3 followed by 0 followed by 0 is another numeral denoting the same number. Different forms of numerals provide convenient ways to express different numbers. A number expressed by a numeral is also called a "constant" (as opposed to a variable.)

We will come back to the topic of numerals: now we return to the topic of different kinds of numbers.

19.1.5 Comparison of Floating-Point Numbers

Two numbers are regarded as equal if their difference is relatively small. For example, we see that a and b have a non-zero difference, but even so the expression a = b produces "true".

a =: 1.001 b =: a - 2^_45 a - b a = b
1.001 1.001 2.84217e_14 1

If we say that the "relative difference" of two numbers is the magnitude of the difference divided by the larger of the magnitudes:

   RD =: (| @: -) % (>. &: |)

then for a=b to be true, the relative difference (a RD b) must not exceed a small value called the "comparison tolerance" which is by default 2^_44

a RD b 2^_44 a = b
2.83933e_14 5.68434e_14 1

Thus to compare two numbers we need to compare relative difference with tolerance. The latter comparison is itself strict, that is, does not involve any tolerance.

Zero is not tolerantly equal to any non-zero number, no matter how small, because the relative difference must be 1, and thus greater than tolerance.

tiny =: 1e_300 tiny = 0 tiny RD 0
1e_300 0 1

However, 1+tiny is tolerantly equal to 1.

tiny tiny = 0 1 = tiny + 1
1e_300 0 1

The value of the comparison tolerance currently in effect is given by the built-in verb 9!:18 applied to a null argument. It is currently 2^_44.

9!:18 '' 2^_44
5.68434e_14 5.68434e_14

Applying the built-in verb 9!:19 to an argument y sets the tolerance to y subsequently. The following example shows that when the tolerance is 2^_44, then a = b but when the tolerance is set to zero it is no longer the case that a = b.

(9!:19) 2^_44 a = b (9!:19) 0 a = b
  1   0

The tolerance queried by 9!:18 and set by 9!:19 is a global parameter, influencing the outcome of computations with =. A verb to apply a specified tolerance t, regardless of the global parameter, can be written as = !. t. For example, strict (zero-tolerance) equality can be defined by:

   streq =: = !.  0

Resetting the global tolerance to the default value, we see:

(9!:19) 2^_44 a - b a = b a streq b
  2.84217e_14 1 0

Comparison with = is tolerant, and so are comparisons with <, <:, >, >:, ~: and -:. For example, the difference a-b is positive but too small to make it true that a>b

a - b a > b
2.84217e_14 0

Permissible tolerances range between 0 and 2^_35. That is, an attempt to set the tolerance larger than 2^_35 is an error:

(9!:19) 2^_35 (9!:19) 2^_34
  error

The effect of disallowing large tolerances is that no two different integers compare equal when converted to floating-point.

19.1.6 Complex Numbers

The square root of -1 is the imaginary number conventionally called "i". A complex number which is conventionally written as, for example, 3+i4 is in J written as 3j4.

In J an imaginary number is represented as a complex number with real part zero. Thus "i", the square root of -1, can be written 0j1.

i =: %: _1 i * i 0j1 * 0j1
0j1 _1 _1

A complex number can be built from two separate real numbers by arithmetic in the ordinary way, or more conveniently with the built-in function j. (lowercase j dot, called "Complex").

3 + (%: _1) * 4 3 j. 4
3j4 3j4

Some more examples of arithmetic with complex numbers:

2j3 * 5j7 10j21 % 5j7 2j3 % 2
_11j29 2.66216j0.472973 1j1.5

A complex number such as 3j4 is a single number, a scalar. To extract its real part and imaginary part separately we can use the built-in verb +.(plus dot, called "Real/Imaginary"). To extract separately the magnitude and angle (in radians) we can use the built-in verb *. (asterisk dot, called "Length/Angle").

+. 3j4 *. 3j4
3 4 5 0.927295

Given a magnitude and angle, we can build a complex number by taking sine and cosine, or more conveniently with the built-in function r. (lowercase r dot, called "Polar").

   sin =: 1 & o.
   cos =: 2 & o.
   mag =: 5
   ang =: 0.92729522  NB. radians

mag * (cos ang) + 0j1 * sin ang mag r. ang
3j4 3j4

A complex constant with magnitude X and angle (in radians) Y can be written in the form XarY, meaning X r. Y. Similarly, if the angle is given in degrees, we can write XadY.

5ar0.9272952 5ad53.1301
3j4 3j4

19.1.7 Extended Integers

A floating-point number, having a limited storage space in the computer's memory, can represent an integer exactly only up to about 17 digits. For exact computations with longer numbers, "extended integers" are available. An "extended integer" is a number which exactly represents an integer no matter how many digits are needed. An extended integer is written with the digits followed with the letter 'x'. Compare the following:

a =: *: 10000000001 b =: *: 10000000001x
1e20 100000000020000000001

Here a is an approximation while b is an exact result.

type a type b
float ext int

We can see that adding 1 to a makes no difference, while adding 1 to b does make a difference:

(a + 1) - a (b + 1) - b
0 1

19.1.8 Rational Numbers

A "rational number" is a single number which represents exactly the ratio of two integers, for example, two-thirds is the ratio of 2 to 3. Two-thirds can be written as a rational number with the notation 2r3.

The point of rationals is that they are are exact representations using extended integers. Arithmetic with rationals gives exact results.

2r3 + 1r7 2r3 * 4r7 2r3 % 5r7
17r21 8r21 14r15

Rationals can be constructed by dividing extended integers. Compare the following:

2 % 3 2x % 3x
0.666667 2r3

A rational can be constructed from a given floating-point number with the verb x:

x: 0.3 x: 1 % 3
3r10 1r3

A rational number can be converted to a floating-point approximation with the inverse ofx: , that is, verb x: ^: _1

float =: x: ^: _1 float 2r3
+--+--+--+
|x:|^:|_1|
+--+--+--+
0.666667

Given a rational number, its numerator and denominator can be recovered with the verb 2 & x:, which gives a list of length 2.

nd =: 2 & x: nd 2r3
+-+-+--+
|2|&|x:|
+-+-+--+
2 3

19.1.9 Type Conversion

We have numbers of six different types: boolean, integer, extended integer, rational, floating-point and complex.

Arithmetic can be done with a mixture of types. For example an integer plus an extended gives an extended, and a rational times a float gives a float.

1 + 10^19x 1r3 * 0.75
10000000000000000001 0.25

The general scheme is that the six types form a progression: from boolean to integer to extended to rational to floating-point to complex. We say that boolean is the simplest or "lowest" type and complex as the most general or "highest" type

Where we have two numbers of different types, the one of lower type is converted to match the type of the higher. and the result is of the "higher".

type 1r3 type 1%3 z =: 1r3, 1%3 type z
rational float 0.333333 0.333333 float

19.2 Special Numbers

19.2.1 "Infinity"

A floating-point number can (on a PC) be no larger than about 1e308, because of the way it is stored in the computer's memory. Any arithmetic which attempts to produce a larger result will in fact produce a special number called "infinity" and written _ (underscore). For example:

1e308 * 0 1 2 1e400 1 % 0
0 1e308 _ _ _

There is also "negative infinity" written as __ (underscore underscore). Infinity is a floating-point number:

   type _
float
   

19.2.2 Indeterminate Numbers

Infinity is equal to infinity. However, infinity minus infinity is not zero but rather a special number called "indeterminate", written as _. (underscore dot)

_ = _ _ - _
1 _.

Indeterminate is equal to indeterminate. However indeterminate minus indeterminate is not zero but indeterminate.

_. = _. _. - _.
1 _.

Computations with indeterminate may produce surprising results. Thus indeterminate is not to be regarded as extending the meaning of "number" according to some extended axiomatization of arithmetic. Rather, the view is recommended that the only purpose of indeterminate is as a signal of numerical error when it occurs in the result of a computation.

Infinity is equal to itself and nothing else, and the same is true of indeterminate. Thus we have a reliable (that is, determinate) test for occurrences.

z =: 1 _ _. z = 1 z = _ z = _.
1 _ _. 1 0 0 0 1 0 0 0 1

19.3 Notations for Numerals

We have seen above numerals formed with the letters e, r and j, for example: 1e3, 2r3, and 3j4. Here we look at more letters for forming numerals.

A numeral written with letter p, of the form XpY means X * pi ^ Y where pi is the familiar value 3.14159265....

pi =: 1p1 twopi =: 2p1 2p_1
3.14159 6.28319 0.63662

Similarly, a numeral written with letter x, of the form XxY means X * e ^ Y where e is the familiar value 2.718281828....

e =: 1x1 2x_1 2 * e ^ _1
2.71828 0.735759 0.735759

These p and x forms of numeral provide a convenient way of writing constants accurately without writing out many digits.

Finally, we can write numerals with a base other than 10. For example the binary or base-2 number with binary digits 101 has the value 5 and can be written as 2b101.

   2b101 
5

The general scheme is that NbDDD.DDD is a numeral in number-base N with digits DDD.DDD . With bases larger than 10, we will need digits larger than 9, so we take letter 'a' as a digit with value 10, 'b' with value 11, and so on up to 'z' with value 35.

For example, letter 'f' has digit-value 15, so in hexadecimal (base 16) the numeral written 16bff has the value 255. The number-base N is given in decimal.

16bff (16 * 15) + 15
255 255

One more example. 10b0.9 is evidently a base-10 number meaning "nine-tenths" and so, in base 20, 20b0.f means "fifteen twentieths"

   10b0.9 20b0.f
0.9 0.75

19.3.1 Combining the Notations

The notation-letters e, r, j ar ad p x and b may be used in combination. For example we can write 1r2p1 to mean "pi over two". Here are some further examples of possible combinations.

A numeral in the form XrY denotes the number X%Y. A numeral in the form XeYrZ denotes the number (XeY) % Z because e is considered before r.

1.2e2 (1.2e2) % 4 1.2e2r4
120 30 30

A numeral in the form XjY denotes the complex number (X j. Y) (that is, (X + (%: _1) * Y). A numeral in the form XrYjZ denotes the number (XrY) j. Z because r is considered before j

3r4 (3r4) j. 5 3r4j5
3r4 0.75j5 0.75j5

A numeral in the form XpY denotes the number X*pi^Y. A numeral in the form XjYpZ denotes (XjY) *pi^Z because j is considered before p.

3j4p5 (3j4) * pi ^ 5
918.059j1224.08 918.059j1224.08

A numeral in the form XbY denotes the number Y-in-base-X. A numeral in the form XpYbZ denotes the number Z-in-base-(XpY) because p is considered before b.

(3*pi)+5 1p1b35
14.4248 14.4248

19.4 How Numbers are Displayed

A number is displayed by J with, by default, up to 6 or 7 significant digits. This means that, commonly, small integers are shown exactly, while large numbers, or numbers with many significant digits, are shown approximately.

10 ^ 3 2.7182818285 2.718281828 * 10 ^ 7
1000 2.71828 2.71828e7

The number of significant digits used for display is determined by a global variable called the "print-precision". If we define the two functions:

   ppq =: 9 !: 10    NB. print-precision query
   pps =: 9 !: 11    NB. print-precision set

then the expression ppq '' gives the value of print-precision currently in effect, while pps n will set the print-precision to n.

ppq '' e =: 2.718281828 pps 8 e
6 2.71828   2.7182818

19.4.1 The "Format" Verb

There is a built-in verb ": (doublequote colon, called "Format"). Monadic Format converts a number into a string representing the number with the print-precision currently in effect. In the following example, note that a is a scalar, while the formatted representation of a is a list of characters.

a =: 1 % 3 ": a $ ": a
0.33333333 0.33333333 10

The argument can be a list of numbers and the result is a single string.

b =: 1 % 3 4 ": b $ b $ ": b
0.33333333 0.25 0.33333333 0.25 2 15

Dyadic Format allows more control over the representation. The left argument is complex: a value of say, 8j4 will format the numbers in a width of 8 characters and with 4 decimal places.

c =: % 1 + i. 2 2 w =: 8j4 ": c $ w
         1  0.5
0.33333333 0.25
  1.0000  0.5000
  0.3333  0.2500
2 16

If the width is specified as zero (as in say 0j3) then sufficient width is allowed. If the number of decimal places is negative (as in 10j_3) then numbers are shown in "scientific notation"

c 0j3 ": c 10j_3 ": c
         1  0.5
0.33333333 0.25
1.000 0.500
0.333 0.250
1.000e0   5.000e_1
3.333e_1  2.500e_1

19.5 Random Numbers

19.5.1 Roll

There are built-in functions for generating random numbers. Monadic ? is called "Roll", because ? n gives the result of rolling a die with n faces marked 0 to n-1.

   ? 6
4

That is, ? n is selected from the items of i. n randomly with equal probability.

A list of random numbers is generated by repeating the n-value. For example, four rolls of a six-sided die is given by

   ? 6 6 6 6
3 4 5 2

or more conveniently by:

   ? 4 $ 6
2 3 5 3

19.5.2 Uniform Distribution

With an argument of zero, monadic ? generates random reals uniformly distributed, greater than 0 and less than 1.

   ? 0 0 0 0
0.14112615 0.083891464 0.41388488 0.055053198
   

19.5.3 Normal Distribution

The built-in verb ? generates equiprobable numbers. Various other distributions are provided by library script statdist.ijs.

   require 'statdist'

Reals normally distributed with mean 0 and standard deviation 1 are generated with normalrand

   normalrand 6
0.84096966 0.59389446 1.5530828 0.69271405 0.87141049 _0.53649589

Other distributions are available in the statdist script.

19.5.4 Deal

Dyadic ? is called "Deal". x ? y is a list of x integers randomly chosen from i. y without replacement, that is, the x integers are all different.

Suppose that cards in a deck are numbered 0 to 51, then 13 ? 52 will deal a single hand of 13 randomly selected cards, all different.

   13 ? 52
28 46 4 24 19 27 5 12 10 13 49 21 42

A shuffle of the whole deck is given by 52 ? 52. To shuffle and then deal four hands:

   4 13 $ 52 ? 52
25 12  1 14 37 29 43 33 27  5 11 26 47
49 23 50  9 39  4 51 18 38 22 19  8  0
24 36 32 10 13 16  6 48 20 42 28 30  3
15 31 21 40  2 45 17 41 35 46  7 44 34
   

This brings us to the end of Chapter 19.


NEXT
Table of Contents
Index


The examples in this chapter were executed using J version 601-o-beta. This chapter last updated 25 Jun 2006 .
Copyright © Roger Stokes 2006. This material may be freely reproduced, provided that this copyright notice is also reproduced.


>>  <<  Ndx  Usr  Pri  JfC  LJ  Phr  Dic  Rel  Voc  !:  wd  Help  Learning J