Part 16: Numbers
Part 1 introduced the number types; this part takes them apart. You will count past 64 bits, ask any type for its limits, meet the float values that are not numbers at all, and work on integers one bit at a time. Above all, you will learn what happens at the edges — when a result does not fit — and how to choose, on purpose, between reporting it, wrapping round and stopping at the limit.
What you will learn
- The wide integers
int128touint512, and the constants every number type carries:Min,Max,Bits,Epsilonand the rest. - Infinity and NaN — where they come from, and why
NaN == NaNisfalse. - Working with bits:
& | ^ ~, the shifts<<,>>and>>>, andCore's counting and rotating functions. - Overflow handled on purpose: checked, wrapping and saturating arithmetic, and conversions that report a value that does not fit.
- Writing a number's bytes in a chosen order, for files and network protocols.
- Roots, powers, logarithms, trigonometry and the four kinds of rounding from the
Mathpackage. - Complex numbers with
Complex: their arithmetic, their length and angle, and the roots of a quadratic that has no real ones.
The part at a glance
flowchart LR
n(["Numbers"]) --> i["Integers"]
n --> f["Floats"]
i --> range["How big?<br/>Wide integer, Number limit"]
i --> bits["Bit by bit<br/>Bitwise, Shift,<br/>Bit operation, Endian"]
i --> edge["When it does not fit<br/>Checked arithmetic,<br/>Wrapping arithmetic,<br/>Checked convert"]
f --> flimit["Limits and precision<br/>Number limit"]
f --> special["Beyond the limits<br/>Float special"]
f --> math["Functions<br/>Math"]
f --> complex["Beyond the real line<br/>Complex"]Lessons
| Lesson | What you will learn | |
|---|---|---|
| 16.1 | Wide integer | 128-, 256- and 512-bit integers |
| 16.2 | Number limit | the smallest and largest value each number type can hold |
| 16.3 | Float special | infinity and NaN, and how they compare |
| 16.4 | Bitwise | &, |, ^ and ~: set, clear, flip and test bits with masks |
| 16.5 | Shift | move bits left and right with <<, >> and >>> |
| 16.6 | Checked arithmetic | detect overflow instead of getting a wrong answer |
| 16.7 | Wrapping arithmetic | arithmetic that wraps around or saturates on purpose |
| 16.8 | Checked convert | convert between number types and detect values that do not fit |
| 16.9 | Bit operation | count, find and rotate bits |
| 16.10 | Endian | write a number's bytes in a chosen byte order |
| 16.11 | Math | roots, powers, logarithms, trigonometry, and rounding |
| 16.12 | Complex | complex numbers: arithmetic, magnitude and polar form |
Before you start
This part draws on almost everything before it. Lessons hand back answers through out-parameters and pointers from Part 15: Memory, report results as optionals from Part 8, and use the generic functions of Core. Each lesson's package is in the Examples repository's Numbers/ folder:
cd Examples/Numbers/WideInteger
rux run
After this part
Part 17: Collections moves from single values to containers of them — vectors, maps, sets and queues. Before moving on, try the checkpoint projects Circle and Quadratic: both put the Math package to work and have to deal with the special values a float calculation can produce. Quadratic works out a complex pair of roots by hand, the job Complex hands to the Complex type.
For the rules behind this part, see Arithmetic, Bitwise and Shift operations, Type casts and the primitive types in the Rux Reference, and the Math API.
15.15 Rc
Share one value between several owners with Rc<T>, whose copies count themselves: the value is read through Get, written through GetMutable only while one handle holds it, and destroyed when the last handle goes.
16.1 Wide integer
Count past 64 bits with int128, int256 and int512 and their unsigned twins: wide literals, silent widening, explicit narrowing, and the same wrap-around at the edges.