
Chapter 19: NumbersThe topics covered in this chapter are:
19.1 Numbers of Six Different KindsJ supports computation with numbers of these kinds:
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)
19.1.1 BooleansThere are builtin functions for logical computation with boolean values. Giving conventional names to these functions:and =: *. or =: +. not =: . notand =: *: notor =: +:we can show their truthtables: p =: 4 1 $ 0 0 1 1 q =: 4 1 $ 0 1 0 1
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)
Notice that in the truthtable above the rows are given in an order such that p,q = successively 00 01 10 11 in binary or 0 1 2 3. Call this the standard order. With the rows of a truthtable in standard order, the resultcolumn can be read as a 4bit number, 1 1 0 1 in this example. This means that there are altogether only 16 possible logical functions of two arguments, and that any of them can be specified by giving its 4bit result. There is a builtin adverb b. (lowercase b dot, called "Boolean"), which can take an integer in the range 015, expressing a 4bit result, and produces the corresponding logical function. For example, we saw above that for logical implication its 4bit specification is 1 1 0 1 or 13, giving us another way to define implication as 13 b. We see:
We regard the booleans as numbers because they can be interpreted as having arithmetic values. To illustrate, implication has the same truthtable as lessthanorequal:
For another example of booleans as numbers, the sum of the positive numbers in a list is shown by:
19.1.2 IntegersOn a 32bit machine integers range between _2147483648 and 2147483647.The result of arithmetic with integers is converted to floatingpoint if larger than the maximum integer.
19.1.3 Bitwise Logical Functions on IntegersJ provides all the expected functions on integers, so not much need be said here. However, this might be a good place to mention that bitwise logical functions on integers are available through the builtin adverb b. we met above. To begin, here is a utility function to show the first and last few bits of an integer (assumed 32bit).bits =: (3 : ' (8{.y), ''...'', (24 }.y) ') @: ({&'01')@:((32#2) & #:)
Recall that logical function k is given by k b. where k is in the range 015. The function (k+16) b. is logically the same, but applies, not to booleans, but to integers bitwise, that is, on machine words. For example (1 b.) is logicaland on booleans, while (17 b.) is logicaland on integers. bits 15 (17 b.) _15 00000000...00000001The verb (32 b.) rotates the bits of y leftward by x places, or rightward for negative x. Similarly (33 b.) shifts and (34 b.) performs a "signed shift" that is, propagating the sign bit on a rightward move. For example: ] bits a =: 1 00000000...00000001 ] bits b =: _1 (32 b.) a NB. rotating rightwards 10000000...00000000 ] bits c =: _1 (34 b.) b NB. shifting right, propagating signbit 11000000...00000000 ] bits d =: 2 (33 b.) c NB. shifting left, removing signbits 00000000...00000000For one more example, recall the Collatz function from Chapter 10 : halve if even, otherwise triple and add one. Here is a bitwise version. odd =: (17 b.) & 1 halve =: _1 & (33 b.) NB. OK for an even number ! triple =: + (1 & (33 b.)) collatz =: halve ` (1 + triple) @. odd collatz ^: (i. 10) 5 5 16 8 4 2 1 4 2 1 4 19.1.4 FloatingPoint NumbersA floatingpoint 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 wholenumber 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 floatingpoint numbers are 0.25 2.5 12345678901 We will use the term "real" more or less interchangeably with "floatingpoint".
19.1.5 Scientific NotationWhat 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).
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.6 Comparison of FloatingPoint NumbersTwo numbers are regarded as equal if their difference is relatively small. For example, we see that a and b have a nonzero difference, but even so the expression a = b produces "true".
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
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 nonzero number, no matter how small, because the relative difference must be 1, and thus greater than tolerance.
However, 1+tiny is tolerantly equal to 1.
The value of the comparison tolerance currently in effect is given by the builtin verb 9!:18 applied to a null argument. It is currently 2^_44.
Applying the builtin 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.
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 (zerotolerance) equality can be defined by: streq =: = !. 0Resetting the global tolerance to the default value, we see:
Comparison with = is tolerant, and so are comparisons with <, <:, >, >:, ~: and :. For example, the difference ab is positive but too small to make it true that a>b
Permissible tolerances range between 0 and 2^_35. That is, an attempt to set the tolerance larger than 2^_35 is an error:
The effect of disallowing large tolerances is that no two different integers compare equal when converted to floatingpoint. 19.1.7 Complex NumbersThe 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.
A complex number can be built from two separate real numbers by arithmetic in the ordinary way, or more conveniently with the builtin function j. (lowercase j dot, called "Complex").
Some more examples of arithmetic with complex numbers:
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 builtin verb +.(plus dot, called "Real/Imaginary"). To extract separately the magnitude and angle (in radians) we can use the builtin verb *. (asterisk dot, called "Length/Angle").
Given a magnitude and angle, we can build a complex number by taking sine and cosine, or more conveniently with the builtin function r. (lowercase r dot, called "Polar"). sin =: 1 & o. cos =: 2 & o. mag =: 5 ang =: 0.92729522 NB. radians
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.
19.1.8 Extended IntegersA floatingpoint 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:
Here a is an approximation while b is an exact result.
We can see that adding 1 to a makes no difference, while adding 1 to b does make a difference:
19.1.9 Rational NumbersA "rational number" is a single number which represents exactly the ratio of two integers, for example, twothirds is the ratio of 2 to 3. Twothirds 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.
Rationals can be constructed by dividing extended integers. Compare the following:
A rational can be constructed from a given floatingpoint number with the verb x:
A rational number can be converted to a floatingpoint approximation with the inverse ofx: , that is, verb x: ^: _1
Given a rational number, its numerator and denominator can be recovered with the verb 2 & x:, which gives a list of length 2.
19.1.10 Type ConversionWe have numbers of six different types: boolean, integer, extended integer, rational, floatingpoint 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.
The general scheme is that the six types form a progression: from boolean to integer to extended to rational to floatingpoint 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".
19.2 Special Numbers19.2.1 "Infinity"A floatingpoint 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:
There is also "negative infinity" written as __ (underscore underscore). Infinity is a floatingpoint number: type _ float 19.2.2 "Indeterminate" NumbersA floatingpoint number is a 64bit value, but not all 64bit values are valid as floatingpoint numbers. Any which is not valid is said to be "Not a Number", or a "NaN". Such a value might occur, for example, in data imported into a J program from an unreliable external source.When displaying the values of numbers, the J system reports any supposed floatingpoint number, which is in fact "Not a Number", as the symbol _. (underbar dot, called "Indeterminate"). Floatingpoint arithmetic on _. arguments cannot be relied upon to produce meaningful results. Thus _. is best regarded solely as a mark of error. The sole reliable test for _. is the verb 128 !: 5 . In the following example note the difference between results of the unreliable test X = _. and the reliable test 128 !: 5 X .
19.3 Number BasesThe number 5 is represented in binary as 1 0 1. There is a built in function, monadic #: ( hash colon, called "Antibase Two" ) to compute the binary digits. Note that the result is a list.#: 5 1 0 1We say that the binary digits are the base2 representation. More generally, a basen representation can be produced. The left argument of dyadic #: (called "Antibase") specifies the both the base and the number of digits. To get four binary digits we can write: 2 2 2 2 #: 5 0 1 0 163 as two base8 (octal) digits: 8 8 #: 63 7 7A mixedbase representation is possible. How many hours, minutes and seconds are there in 7265 seconds? 24 60 60 #: 7265 2 1 5The inverse functions produce numbers from lists of digits in specified bases. Monadic #. is called "Base Two". Binary 1 0 1 is 5 #. 1 0 1 5Dyadic #. is called "Base". Its left argument specifies a numberbase for the digits of the right argument. 2 #. 1 0 1 5Equivalently: 2 2 2 #. 1 0 1 5There must be a base specified on the left for each digit on the right, otherwise an error is signalled 2 2 #. 1 0 1 length error  2 2 #.1 0 1 [535] c:\users\homer\14\js\19.ijsAgain, mixed bases are possible: 2 hours 1 minute 5 seconds is 7265 seconds 24 60 60 #. 2 1 5 7265 19.4 Notations for NumeralsWe 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....
Similarly, a numeral written with letter x, of the form XxY means X * e ^ Y where e is the familiar value 2.718281828....
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 base2 number with binary digits 101 has the value 5 and can be written as 2b101. 2b101 5The general scheme is that NbDDD.DDD is a numeral in numberbase 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 digitvalue 15, so in hexadecimal (base 16) the numeral written 16bff has the value 255. The numberbase N is given in decimal.
One more example. 10b0.9 is evidently a base10 number meaning "ninetenths" and so, in base 20, 20b0.f means "fifteen twentieths" 10b0.9 20b0.f 0.9 0.75 19.4.1 Combining the NotationsThe notationletters 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.
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
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.
A numeral in the form XbY denotes the number YinbaseX. A numeral in the form XpYbZ denotes the number Zinbase(XpY) because p is considered before b.
19.5 How Numbers are DisplayedA 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.
The number of significant digits used for display is determined by a global variable called the "printprecision". If we define the two functions: ppq =: 9 !: 10 NB. printprecision query pps =: 9 !: 11 NB. printprecision setthen the expression ppq '' gives the value of printprecision currently in effect, while pps n will set the printprecision to n.
19.5.1 The "Format" VerbThere is a builtin verb ": (doublequote colon, called "Format"). Monadic Format converts a number into a string representing the number with the printprecision currently in effect. In the following example, note that a is a scalar, while the formatted representation of a is a list of characters.
The argument can be a list of numbers and the result is a single string.
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.
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"
Note that monadic format shows a complex number in the usual way, but dyadic format shows only the real part of a complex number.
More formatting options are provided by the builtin verbs 8!:n. Here is a small example to show a few of the many options described in the J dictionary. Suppose our table of numbers to be formatted is N ] N =: 3 2 $ 3.8 _2000 0 123.45 _3.14 15000 3.8 _2000 0 123.45 _3.14 15000We can format each column of N separately. Suppose numbers in the first column are to be presented as blank when zero, 6 characters wide with 0 decimal places. We write a "formatting phrase" like this fp1 =: 'b6.0'Here the 'b' means blank when zero. Suppose for the second column we require a comma between each 3 digits. We require negative numbers to be shown with a following "CR" and therefore nonnegative numbers should be followed by two blank characters, so that decimal points line up vertically. We require a 12character width with 2 decimal places. A suitable formatting phrase is like this: fp2 =: 'cn{CR}q{ }12.2'Here the 'c' means commas, n{CR} means CR after a negative number and q{ } means 2 spaces after a nonnegative. Applying the formatting verb 8!:2 we see
The formatted result is a character table of dimensions 3 by 18, because N has 3 rows, and we specified widths of 6 and 12 for first and second columns. $ (fp1;fp2) (8!:2) N 3 18 19.6 Random Numbers19.6.1 RollThere are builtin functions for generating random numbers. Monadic ? is called "Roll", because ? n gives the result of rolling a die with n faces marked 0 to n1.? 6 4That is, ? n is selected from the items of i. n randomly with equal probability. A list of random numbers is generated by repeating the nvalue. For example, four rolls of a sixsided die is given by ? 6 6 6 6 3 4 5 2or more conveniently by: ? 4 $ 6 2 3 5 3 19.6.2 Uniform DistributionWith 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.6.3 Other DistributionsThe builtin verb ? generates equiprobable numbers. Various other distributions are provided by the J Application Library stats/distribs Addon19.6.4 DealDyadic ? 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 44 2 36 30 0 6 43 26 28 1 34 48 41A shuffle of the whole deck is given by 52 ? 52. To shuffle and then deal four hands: 4 13 $ 52 ? 52 15 18 3 8 11 25 27 51 20 31 50 48 35 45 39 21 29 10 33 32 41 36 0 34 16 22 19 14 37 2 24 42 6 7 30 46 47 28 26 38 23 40 13 4 9 5 12 49 1 44 43 17This brings us to the end of Chapter 19. 
The examples in this chapter
were executed using J version 701.
This chapter last updated 02 Jul 2013
Copyright © Roger Stokes 2012.
This material may be freely reproduced,
provided that this copyright notice is also reproduced.