When writing software, we need a full, detailed understanding of how computers work with numbers. Inadequate understanding can have dire consequences. In Numbers and computers, Kneusel mentions two egregious examples: the explosion of an Ariane rocket , and the failure of a Patriot missile to even attempt to intercept a Scud missile that killed 28 American soldiers . Both failures were due to software arithmetic errors. So his aim is to explore--“in sufficient, but not overwhelming, detail”--how computers represent and manipulate numbers. In this, he succeeds brilliantly.
This book can be profitably read by anyone who is interested in computers and is willing to occasionally slog through perhaps unfamiliar territory with minimal guidance. For the most part, however, details are explained thoroughly, with utmost clarity and specificity. Each chapter ends with a summary, recommendations, exercises, and a set of carefully selected references.
This small book provides a solid foundation for further exploration and study. It can be especially valuable to computer science and electrical engineering students. Some readers may find it challenging; for others, it may expand their horizons. All readers, though, will appreciate the clarity of the exposition: Kneusel uses as many words as needed to explain a topic, but no more than needed. Kneusel’s style can serve as an example of scientific writing and software documentation.
The book’s website (http://www.numbersandcomputers.com/) has a good overview of the contents and a link to the accompanying C and Python source code.
The contents are grouped into two parts. Part 1, “Standard Representations,” begins with an introduction to number systems, and proceeds to deal in minute detail with integers and floating-point numbers in the familiar base 2 notation that we have come to associate with computers.
The treatment of number systems includes one’s complement and two’s complement notations for binary systems, plus hexadecimal notation. Babylonian and Mayan systems are also introduced briefly.
Integer binary representations are thoroughly reviewed. Comparisons, rotations, and arithmetic operations through bit-twiddling are illustrated using C code. Integers represented in binary-coded decimal notation are reviewed rather briefly.
For floating-point numbers, the current IEEE 754 standard is reviewed thoroughly, but the now-obsolete IBM S/360 base 64 format is also summarized briefly. Algorithms to implement logic and arithmetic operations are developed and implemented in C. A few rules of thumb to avoid potential pitfalls are given (this is one of the rare occasions where I felt that more should have been said).
Part 2, “Other Representations,” deals with big integers, rational arithmetic, fixed-point numbers, decimal floating-point numbers, and interval arithmetic.
Big integers are treated rather thoroughly. Big integer representation is illustrated using base 10,000, and basic integer arithmetic operations are developed in C. Additional algorithms are summarized: for multiplication, the Comba algorithm, the Karatsuba algorithm, and the Schönhage-Strassen algorithm; for division, the Knuth algorithm D and the Burnikel-Ziegler algorithm. Implementation and language support issues in Scheme, Java, and Python are discussed. The GNU Multiple Precision Library is carefully reviewed.
Rational arithmetic using big integers is investigated; a Python class for rational arithmetic is developed.
Fixed-point numbers expressed in the Qm.n notation are thoroughly explored, and a basic implementation library that includes trigonometric functions, square roots, and the exponential function is developed. Recommendations for when to use fixed-point numbers are included.
For decimal floating-point numbers, the IEEE 754-2008 decimal floating-point format standard is explained. This format is frankly difficult to grasp, and the code to implement it is difficult to understand without explanation. C routines are given to parse a decimal64 number. Rounding options (count them: ten) are listed. However, a basic arithmetic library for decimal floating is not developed. Kneusel recommends asking: “Is there any valid reason why I should not use decimal floating point?”
For interval arithmetic, the basic operations are explained using mathematical notation. Potential pitfalls are mentioned. A basic C library and a Python class are developed. Use of the MPFR and MPFI libraries is illustrated.
I enjoyed the book a great deal--I learned more than I expected. I recommend it highly.