fastmath

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 6, 2021 License: MIT Imports: 0 Imported by: 0

README

FastMath for Go

"I can make things very fast if they don’t have to be correct." — Russ Cox

8 and 16 bit math functions for when speed matters more than precision. Potential use cases include LED displays, 2D/3D graphics, and games.

Functions

  • Sin8() / Sin16()
  • Cos8() / Cos16()
  • Random8() / Random16()
  • Random8Limit() / Random16Limit()
  • Random8Range() / Random16Range()
  • Random16SetSeed() / Random16GetSeed() / Random16AddEntropy()
  • Scale8() / Scale8Video()
  • NScale8x3() / NScale8x3Video() - Scale three 8 bit integers at the same time.
  • Scale16() / Scale16By8()
  • QAdd8() / QSub8() / QMul8() - Saturating non-overflowing math functions.
  • Abs8()
  • Sqrt16()

Note: Functionality already well handled by the Go runtime has not be re-implemented.

Approximation Error

Computer-based math functions have an error delta verses the pure mathematical results. The Golang Standard Library's math functions are precise up to 64 bit floats. The math functions provided by this library sacrifice additional precision for speed by working with small integers.

  • Sin8() - Max Error: 1.63%, Average Error: 0.78%
  • Sin16() - Max Error: 0.34%, Average Error: 0.19%

Benchmarks

Run on a Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz.

BenchmarkStdLibFallbackSqrt-4   20000000                 50.7 ns/op
BenchmarkStdLibDefaultSqrt-4    2000000000               0.30 ns/op
BenchmarkSqrt16-4               200000000                9.12 ns/op
BenchmarkStdLibRandom8-4        50000000                 25.6 ns/op
BenchmarkRandom8-4              1000000000               2.12 ns/op
BenchmarkStdLibSin8-4           50000000                 20.8 ns/op
BenchmarkSin8-4                 300000000                4.07 ns/op
BenchmarkStdLibSin16-4          50000000                 20.0 ns/op
BenchmarkSin16-4                2000000000               0.94 ns/op

Random8(), Sin8() and Sin16() are significantly faster than using the equivalent Go Standard Library's Math package functions.

Sqrt16() is compared against both the default compiled math.Sqrt() and a copy of the fallback Standard Library sqrt() function. The default version is optimized by the Go compiler into a single instruction on the AMD64 architecture, so the fallback version is used for a fair comparison.

TODO

  • Should Sin8() be a lookup table? Why is it 4ns/op vs Sin16()@0.9ns/op?
  • Add ARM assembly implementations from upstream, benchmark difference.

License

Licensed MIT

© 2019 Brad Erickson

Based on FastLED MIT-licensed code:

© 2013 FastLED

Parts of test-only BSD code:

© 2009 The Go Authors

Documentation

Index

Constants

View Source
const PI16 uint16 = 32768

PI16 is the value of π in 16 bit math.

View Source
const PI8 uint8 = 127

PI8 is the value of π in 8 bit math.

Variables

This section is empty.

Functions

func Abs8

func Abs8(i int8) int8

Abs8 finds the absolute value of a signed 8-bit int8

func Cos16

func Cos16(theta uint16) int16

Cos16 is a fast 16-bit approximation of cos(x). This approximation never varies more than 0.69% from the floating point value.

Accepts theta input angle from 0-65535. Returns sin of theta, value between -32767 to 32767.

func Cos8

func Cos8(theta uint8) uint8

Cos8 is a fast 8-bit approximation of cos(x). This approximation never varies more than 2% from the floating point value.

Accepts theta input angle from 0-255 Returns sin of theta, value between 0 and 255

func NScale8x3

func NScale8x3(r, g, b *uint8, scale uint8)

NScale8x3 scales three one byte values by a fourth one, which is treated as the numerator of a fraction whose demominator is 256. In other words, it computes r,g,b * (scale / 256).

func NScale8x3Video

func NScale8x3Video(r, g, b *uint8, scale uint8)

NScale8x3Video scale three one byte values by a fourth one, which is treated as the numerator of a fraction whose demominator is 256. In other words, it computes r,g,b * (scale / 256), ensuring that non-zero values passed in remain non zero, no matter how low the scale argument.

func QAdd8

func QAdd8(i, j uint8) uint8

QAdd8 adds one byte to another, saturating at 0xFF. Accepts: * i - first byte to add * j - second byte to add Returns the sum of i & j, capped at 0xFF

func QMul8

func QMul8(i, j uint8) uint8

QMul8 performs saturating 8x8 bit multiplication, with 8 bit result. Returns the product of i * j, capping at 0xFF

func QSub8

func QSub8(i, j uint8) uint8

QSub8 subtracts one byte from another, saturating at 0x00. Returns i - j with a floor of 0

func Random16

func Random16() uint16

Random16 generates a 16 bit random number.

func Random16AddEntropy

func Random16AddEntropy(entropy uint16)

Random16AddEntropy adds entropy into the random number generator.

func Random16GetSeed

func Random16GetSeed() uint16

Random16GetSeed gets the current seed value for the random number generator.

func Random16Limit

func Random16Limit(lim uint16) uint16

Random16Limit generates an 16-bit random number between 0 and lim. Accepts lim the upper bound for the result

func Random16Range

func Random16Range(min, lim uint16) uint16

Random16Range generates an 16-bit random number in the given range. Accept min the lower bound for the random number Return lim the upper bound for the random number

func Random16SetSeed

func Random16SetSeed(seed uint16)

Random16SetSeed sets the 16-bit seed used for the random number generator.

func Random8

func Random8() uint8

Random8 generates an 8-bit random number.

func Random8Limit

func Random8Limit(lim uint8) uint8

Random8Limit generates an 8-bit random number between 0 and lim. Accept lim the upper bound for the result

func Random8Range

func Random8Range(min, lim uint8) uint8

Random8Range generates an 8-bit random number in the given range. Accepts min the lower bound for the random number Accepts lim the upper bound for the random number

func Scale16

func Scale16(i, scale uint16) uint16

Scale16 scales a 16-bit unsigned value by a 16-bit value, considered as numerator of a fraction whose denominator is 65536. In other words, it computes i * (scale / 65536).

func Scale16By8

func Scale16By8(i uint16, scale uint8) uint16

Scale16By8 scales a 16-bit unsigned value by an 8-bit value, considered as numerator of a fraction whose denominator is 256. In other words, it computes i * (scale / 256).

func Scale8

func Scale8(i uint8, scale uint8) uint8

Scale8 scales one byte by a second one, which is treated as the numerator of a fraction whose denominator is 256. In other words, it computes i * (scale / 256)

func Scale8Video

func Scale8Video(i, scale uint8) uint8

Scale8Video is the "video" version of Scale8. Guarantees the output will be only be zero if one or both of the inputs are zero. If both inputs are non-zero, the output is guaranteed to be non-zero. This makes for better 'video'/LED dimming, at the cost of several additional cycles.

func Sin16

func Sin16(theta uint16) int16

Sin16 is a fast 16-bit approximation of sin(x). This approximation never varies more than 0.69% from the floating point value.

This is a Golang translation of the FastLED lib8tion sin16_C() function. https://raw.githubusercontent.com/FastLED/FastLED/dcbf3993/lib8tion/trig8.h

Accepts theta input angle from 0-65535. Returns sin of theta, value between -32767 to 32767.

func Sin8

func Sin8(theta uint8) uint8

Sin8 is a fast 8-bit approximation of sin(x). This approximation never varies more than 2% from the floating point value.

This is a Golang translation of the FastLED lib8tion sin8_C() function. https://raw.githubusercontent.com/FastLED/FastLED/dcbf3993/lib8tion/trig8.h

Accepts theta input angle from 0-255. Returns sin of theta, value between 0 and 255

func Sqrt16

func Sqrt16(x uint16) uint8

Sqrt16 finds the square root for 16-bit integers. This function is significantly slower, ~20X, on Intel/AMD CPUs. It should be much faster on a microcontroller though.

Note: Sqrt is implemented in assembly on some systems. Others have assembly stubs that jump to func sqrt below. On systems where Sqrt is a single instruction, the compiler may turn a direct call into a direct use of that instruction instead. src: https://golang.org/src/math/sqrt.go

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL