Last active
June 1, 2021 15:39
-
-
Save going-digital/4df9c953077ec85d26e031bf813ac4d2 to your computer and use it in GitHub Desktop.
exp2 in WebAssembly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Calculate exp2(x) = 2**x natively in WebAssembly. | |
;; Compiles to 49 bytes of WebAssembly code | |
(module | |
(func $exp2 (param $x f32) (result f32) | |
(local $xf f32) | |
;; Parse result as a float bitfield | |
(f32.reinterpret_i32 | |
(i32.add | |
;; Compute mantissa of result | |
;; Compute polynomial to cover f(x) = 2**23 * ( 2^(x) - 1 ) where 0 <= x < 1 | |
;; This computes the result mantissa. | |
;; | |
;; These coefficients were based on Excel solver. I initially used Taylor series, but the | |
;; Excel solver gives better accuracy across whole range as it spreads the error better. | |
;; Errors in musical cents (1 octave = 12 semitones = 1200 cents). Human ear can resolve about 1 cent. | |
;; 2 terms: 22743533, 5603139 : 16 cents error | |
;; 3 terms: 642218, 1911078, 5832153 : 0.6 cents error | |
;; 4 terms: 120819, 421063, 2035288, 5811427 : 0.05 cents error | |
(i32.trunc_f32_u | |
(f32.mul | |
(f32.add | |
(f32.const 5832153) | |
(f32.mul | |
(f32.add | |
(f32.const 1911078) | |
(f32.mul | |
(f32.const 642218) | |
(local.tee $xf | |
;; Compute xf = fract(x) | |
(f32.sub | |
(local.get $x) | |
(f32.floor | |
(local.get $x) | |
) | |
) | |
) | |
) | |
) | |
(local.get $xf) | |
) | |
) | |
(local.get $xf) | |
) | |
) | |
;; Compute exponent of result | |
(i32.shl | |
(i32.add | |
(i32.trunc_f32_s | |
(f32.floor | |
(local.get $x) | |
) | |
) | |
(i32.const 127) | |
) | |
(i32.const 23) | |
) | |
) | |
) | |
) | |
(export "exp2" (func $exp2)) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment