Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The numeric library

#import "std/numeric" adds the functions the built-ins lack, each named for exactly what it does. Nothing existing changes: int, mod and ^ behave as before, and the library adds correct neighbours under other names.

#import "std/numeric"

'' Rounding that says which way it goes.
print "Round( 2.5 ) ="; numeric.Round( 2.5 ); _
      ", Round( -2.5 ) ="; numeric.Round( -2.5 )
print "RoundHalfEven( 2.5 ) ="; numeric.RoundHalfEven( 2.5 ); _
      ", RoundHalfEven( 3.5 ) ="; numeric.RoundHalfEven( 3.5 )
print "Floor( -1.5 ) ="; numeric.Floor( -1.5 ); _
      ", Ceil( -1.5 ) ="; numeric.Ceil( -1.5 ); _
      ", Truncate( -1.5 ) ="; numeric.Truncate( -1.5 )
print "Round( 3.14159, 2 ) ="; numeric.Round( 3.14159, 2 )

'' Selection.
print "Min ="; numeric.Min( 3, 8 ); ", Max ="; numeric.Max( 3, 8 ); _
      ", Clamp( 15, 0, 10 ) ="; numeric.Clamp( 15, 0, 10 )
print "Lerp( 0, 200, 0.25 ) ="; numeric.Lerp( 0.0, 200.0, 0.25 )

'' Constants and geometry.
print "PI ="; numeric.PI; ", Hypot( 3, 4 ) ="; numeric.Hypot( 3.0, 4.0 )
print "Log2( 1024 ) ="; numeric.Log2( 1024.0 ); _
      ", Log10( 1000 ) ="; numeric.Log10( 1000.0 )

'' Whole-number work, done exactly.
print "IPow( 3, 4 ) ="; numeric.IPow( 3, 4 ); _
      ", ISqrt( 99 ) ="; numeric.ISqrt( 99 )
print "GCD( 12, 18 ) ="; numeric.GCD( 12, 18 ); _
      ", LCM( 4, 6 ) ="; numeric.LCM( 4, 6 )

'' A remainder that never goes negative, for wrapping around.
print "-7 mod 3 ="; -7 mod 3; ", FloorMod( -7, 3 ) ="; _
      numeric.FloorMod( -7, 3 )

'' Quotient and remainder together, as a tuple.
var ( pages, rest ) = numeric.DivMod( 47, 10 )
print "47 lines, 10 a page:"; pages; " full pages and"; rest; " over"

Output

Round( 2.5 ) = 3, Round( -2.5 ) =-3
RoundHalfEven( 2.5 ) = 2, RoundHalfEven( 3.5 ) = 4
Floor( -1.5 ) =-2, Ceil( -1.5 ) =-1, Truncate( -1.5 ) =-1
Round( 3.14159, 2 ) = 3.14
Min = 3, Max = 8, Clamp( 15, 0, 10 ) = 10
Lerp( 0, 200, 0.25 ) = 50
PI = 3.141592653589793, Hypot( 3, 4 ) = 5
Log2( 1024 ) = 10, Log10( 1000 ) = 3
IPow( 3, 4 ) = 81, ISqrt( 99 ) = 9
GCD( 12, 18 ) = 6, LCM( 4, 6 ) = 12
-7 mod 3 =-1, FloorMod( -7, 3 ) = 2
47 lines, 10 a page: 4 full pages and 7 over

Rounding. Round takes a half away from zero; RoundHalfEven takes it to the even neighbour, which is banker's rounding. Both take an optional number of decimal places. Floor, Ceil and Truncate say which way they go.

Selection. Min, Max and Clamp( v, lo, hi ) work on every numeric type; Lerp( a, b, t ) moves from a toward b by the fraction t.

Constants and functions. PI, TAU, E, SQRT2, LN2 and LN10; Hypot, which does not overflow where sqr( x * x + y * y ) would; Log2, Log10, Cbrt, Pow and the hyperbolic functions.

Whole numbers. IPow multiplies integers, so it is exact where ^ rounds (see Overflow). ISqrt, GCD and LCM are exact too. FloorMod takes the sign of the divisor, so it is never negative for a positive divisor: the remainder you want for wrapping an index around. DivMod returns the quotient and remainder together as a tuple, which var ( pages, rest ) = ... takes apart.

The module's names are reached through numeric., or bare after using numeric.

Activities

  1. Round 2.5, 3.5 and 4.5 with both Round and RoundHalfEven.
  2. Use FloorMod to step backwards through the days of the week 0 to 6, starting at 2 and wrapping past 0.