Skip to content

Commit e26734e

Browse files
committed
Implement Math/Mathf.exp; Initial math test suite
1 parent 70d2a0a commit e26734e

File tree

12 files changed

+7990
-803
lines changed

12 files changed

+7990
-803
lines changed

dist/asc.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/asc.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/hexfloat.html

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<style>
2+
html, body { margin: 0; }
3+
body { font-family: sans-serif; border-top: 5px solid #0074C1; }
4+
form { margin: 10px; }
5+
label { cursor: pointer; }
6+
</style>
7+
8+
<script src="hexfloat.js"></script>
9+
<form onsubmit="convert(this); return false">
10+
<h1>Hexadecimal float to decimal float converter</h1>
11+
<p>
12+
<label for="f64"><input id="f64" name="precision" value="f64" type="radio" checked /> f64</label>
13+
<label for="f32"><input id="f32" name="precision" value="f32" type="radio" /> f32</label>
14+
<input id="name" type="text" value="test(" />
15+
<button>Convert</button>
16+
</p>
17+
<p><textarea cols="120" rows="20" id="input"></textarea></p>
18+
<p><textarea cols="120" rows="20" id="output" readonly></textarea></p>
19+
</form>
20+
21+
<script>
22+
function convert(form) {
23+
var isF64 = document.getElementById("f64").checked;
24+
var name = document.getElementById("name").value;
25+
var input = document.getElementById("input").value;
26+
document.getElementById("output").value = input
27+
.replace(/\b(\-?0x[0-9a-fA-F]*(?:\.[0-9a-fA-F]+)?[pP][+-]?[0-9]+\b)/g, ($0, $1) => {
28+
var val = parse($1);
29+
return val.toPrecision(isF64 ? 18 : 10);
30+
})
31+
.replace(/\bnan\b/g, "NaN")
32+
.replace(/\inf\b/g, "Infinity")
33+
.replace(/^T\(RN, */mg, name + "(")
34+
.replace(/\)$/mg, ");")
35+
.replace(/ +/g, " ");
36+
}
37+
</script>

scripts/hexfloat.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2017 Mauro Bringolf
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
// see: https://github.com/maurobringolf/webassembly-floating-point-hex-parser
25+
function parse(input) {
26+
input = input.toUpperCase();
27+
const splitIndex = input.indexOf('P');
28+
let mantissa, exponent;
29+
30+
if (splitIndex !== -1) {
31+
mantissa = input.substring(0, splitIndex);
32+
exponent = parseInt(input.substring(splitIndex + 1));
33+
} else {
34+
mantissa = input;
35+
exponent = 0;
36+
}
37+
38+
const dotIndex = mantissa.indexOf('.');
39+
40+
if (dotIndex !== -1) {
41+
let integerPart = parseInt(mantissa.substring(0,dotIndex), 16);
42+
let sign = Math.sign(integerPart);
43+
integerPart = sign * integerPart;
44+
const fractionLength = mantissa.length - dotIndex - 1;
45+
const fractionalPart = parseInt(mantissa.substring(dotIndex + 1), 16);
46+
const fraction = fractionLength > 0 ? fractionalPart / Math.pow(16, fractionLength) : 0;
47+
if (sign === 0) {
48+
if (fraction === 0) {
49+
mantissa = sign;
50+
} else {
51+
if (Object.is(sign, -0)) {
52+
mantissa = - fraction;
53+
} else {
54+
mantissa = fraction;
55+
}
56+
}
57+
} else {
58+
mantissa = sign * (integerPart + fraction);
59+
}
60+
} else {
61+
mantissa = parseInt(mantissa, 16);
62+
}
63+
64+
return mantissa * (splitIndex !== -1 ? Math.pow(2, exponent) : 1);
65+
}
66+
67+
if (typeof process !== "undefined") {
68+
if (process.argv.length < 3) {
69+
console.error("Usage: hexfloat 0x1p1023");
70+
process.exit(1);
71+
}
72+
73+
var output = parse(process.argv[2]);
74+
var double = output.toPrecision(18); // 17
75+
var single = output.toPrecision(10); // 9
76+
77+
console.log("<f64>" + double);
78+
console.log("<f32>" + single);
79+
80+
if (!(parseFloat(double) === output)) throw Error("double precision error");
81+
if (!(Math.fround(parseFloat(single)) === Math.fround(output))) throw Error("single precision error");
82+
}

src/tokenizer.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,20 @@ export class Tokenizer extends DiagnosticEmitter {
12691269
}
12701270

12711271
readFloat(): f64 {
1272+
// var text = this.source.text;
1273+
// if (text.charCodeAt(this.pos) == CharCode._0 && this.pos + 2 < this.end) {
1274+
// switch (text.charCodeAt(this.pos + 1)) {
1275+
// case CharCode.X:
1276+
// case CharCode.x: {
1277+
// this.pos += 2;
1278+
// return this.readHexFloat();
1279+
// }
1280+
// }
1281+
// }
1282+
return this.readDecimalFloat();
1283+
}
1284+
1285+
readDecimalFloat(): f64 {
12721286
var start = this.pos;
12731287
var text = this.source.text;
12741288
while (this.pos < this.end && isDecimalDigit(text.charCodeAt(this.pos))) {
@@ -1300,6 +1314,10 @@ export class Tokenizer extends DiagnosticEmitter {
13001314
return parseFloat(text.substring(start, this.pos));
13011315
}
13021316

1317+
readHexFloat(): f64 {
1318+
throw new Error("not implemented"); // TBD
1319+
}
1320+
13031321
readUnicodeEscape(): string {
13041322
var remain = 4;
13051323
var value = 0;

std/assembly.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ declare namespace Math {
411411
export function abs(x: f64): f64;
412412
export function ceil(x: f64): f64;
413413
export function clz32(x: f64): i32;
414+
export function exp(x: f64): f64;
414415
export function floor(x: f64): f64;
415416
export function fround(x: f64): f32;
416417
export function imul(a: f64, b: f64): i32;
@@ -433,6 +434,7 @@ declare namespace Mathf {
433434
export const SQRT1_2: f32;
434435
export const SQRT2: f32;
435436
export function abs(x: f32): f32;
437+
export function exp(x: f32): f32;
436438
export function ceil(x: f32): f32;
437439
export function clz32(x: f32): i32;
438440
export function floor(x: f32): f32;

0 commit comments

Comments
 (0)