Thanks, and a possible example to add: faking a C-stye union
- Dominant language
- JavaScript
- Stars
- 4.6k
- Forks
- 119
- PR merge metrics
- No merged PRs in 30d
Description
So this week, as an experiment, I ported [Paul Mineiro's fast log2 approximation](http://www.machinedlearnings.com/2011/06/fast-approximate-logarithm-exponential.html) ([original C repo here](https://github.com/romeric/fastapprox/)) to plain JavaScript:
```js
// Fake a C-union using a typed array
const unionU32 = new Uint32Array(1),
unionF32 = new Float32Array(unionU32.buffer);
function fastlog2(x) {
unionF32[0] = x;
let vx_u = unionU32[0];
unionU32[0] = (vx_u & 0x007FFFFF) | 0x3F000000;
let mx_f = unionF32[0];
return (vx_u * 1.1920928955078125e-7) - 124.22551499 - 1.498030302 * mx_f - 1.72587999 / (0.3520887068 + mx_f);
}
```
It actually seems to be slightly faster, despite all the overhead involved. Then I figured *"I wonder if WASM works... but I don't want to involve a big toolchain just to test that"*. A bit of searching later, I found Walt, and using your on-line explorer I created this:
```js
const memory: Memory = { 'initial': 1 };
export function fastlog2(x: f32): f32 {
// To use arrays simple define a type with array subscript
// Assign arrays to the same address to mimic a C-union
const uf: f32[] = 1;
const ui: i32[] = 1;
uf[0] = x;
let vx_u : i32 = ui[0];
ui[0] = (vx_u & 8388607) | 1056964608;
let mx_f : f32 = uf[0];
return (vx_u * 0.00000011920928955078125) - 124.22551499 - 1.498030302 * mx_f - 1.72587999 / (0.3520887068 + mx_f);
}
```
... which I extracted (quite crudely), by typing this in the JS tab of the explorer:
```js
function compile(buffer) {
console.log(Array.from(new Uint8Array(buffer)))
}
```
... the output of which was then copied turned into a quick-and-dirty function like this:
```js
WebAssembly.instantiate(Uint8Array.from([0, 97, 115, 109, 1, 0, 0, 0, 1, 6, 1, 96, 1, 125, 1, 125, 3, 2, 1, 0, 5, 3, 1, 0, 1, 7, 12, 1, 8, 102, 97, 115, 116, 108, 111, 103, 50, 0, 0, 10, 125, 1, 123, 4, 1, 127, 1, 127, 1, 127, 1, 125, 65, 1, 33, 1, 65, 1, 33, 2, 32, 1, 65, 0, 65, 2, 116, 106, 32, 0, 56, 2, 0, 32, 2, 65, 0, 65, 2, 116, 106, 40, 2, 0, 33, 3, 32, 2, 65, 0, 65, 2, 116, 106, 32, 3, 65, 255, 255, 255, 3, 113, 65, 128, 128, 128, 248, 3, 114, 54, 2, 0, 32, 1, 65, 0, 65, 2, 116, 106, 42, 2, 0, 33, 4, 32, 3, 178, 67, 0, 0, 0, 52, 148, 67, 119, 115, 248, 66, 147, 67, 117, 191, 191, 63, 32, 4, 148, 147, 67, 163, 233, 220, 63, 67, 249, 68, 180, 62, 32, 4, 146, 149, 147, 15, 11]).buffer).then(result => console.log([0,1,2,3,4,5,67,8,9,10,11,12].map(v => result.instance.exports.fastlog2(v))));
// => [
// -127, -0.000002384185791015625,
// 0.999997615814209,
// 1.584951639175415,
// 1.9999973773956299,
// 2.321864604949951,
// 6.065983772277832,
// 2.99999737739563,
// 3.1697850227355957,
// 3.321864604949951,
// 3.45943021774292,
// 3.584951639175415
// ]
```
It seems to work! Now I just have to figure out how to benchmark it.
Anyway, I haven't seen any examples discussion unions so far. Perhaps this could work for that purpose?
Contributor guide
Research direction
Start with the Walt online explorer and the typed-array and array-aliasing examples shown in the issue. Check whether the proposed union example fits the project's existing example or documentation structure, and verify that it compiles and produces the demonstrated fastlog2 results. Done means the example's placement and expected behavior are documented clearly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, wasm
- Domain
- compilers, documentation
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100