js-hexfloat
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -22,17 +22,13 @@ /* | ||
}; | ||
var toHexString = function(canonical) { | ||
var toHexString = function() { | ||
var sign = this < 0 ? '-' : ''; | ||
if (!canonical) { | ||
return sign + '0x' + Math.abs(this).toString(16) + 'p0'; | ||
var a = Math.abs(this); | ||
var p = 0; | ||
if (a < 1) { | ||
while (a < 1) { a *= 2; p-- } | ||
} else { | ||
var a = Math.abs(this); | ||
var p = 0; | ||
if (a < 1) { | ||
while (a < 1) { a *= 2; p-- } | ||
} else { | ||
while (a > 2) { a /= 2; p++ } | ||
} | ||
var es = p < 0 ? '' : '+'; | ||
return sign + '0x' + a.toString(16) + 'p' + es + p.toString(10); | ||
while (a > 2) { a /= 2; p++ } | ||
} | ||
var es = p < 0 ? '' : '+'; | ||
return sign + '0x' + a.toString(16) + 'p' + es + p.toString(10); | ||
}; | ||
@@ -39,0 +35,0 @@ // install |
{ | ||
"name": "js-hexfloat", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "Rudimentary C99 Hexadecimal Float Support in JS", | ||
@@ -5,0 +5,0 @@ "main": "hexfloat.js", |
@@ -11,3 +11,3 @@ [![build status](https://secure.travis-ci.org/dankogai/js-hexfloat.png)](http://travis-ci.org/dankogai/js-hexfloat) | ||
var pi = parseHexFloat('0x1.921fb54442d18p+1'); // 3.14159265358982 | ||
var piHex = Math.PI.toHexString(); // '0x3.243f6a8885a3p0' | ||
var piHex = Math.PI.toHexString(); // '0x1.921fb54442d18p+1' | ||
parseHexFloat(piHex) == Math.PI; // true | ||
@@ -36,23 +36,31 @@ ```` | ||
### `Number.prototype.toHexString(canonical)` | ||
### `Number.prototype.toHexString()` | ||
Stringifies the number as a C99 hexadecimal notation. Analogous to `"%a"` in C99 `sprintf()`. | ||
Stringifies the number as a C99 hexadecimal notation like `"%a"` in C99 `sprintf()`. | ||
#### CAVEAT | ||
#### Why Canonical Form? | ||
Unless `canonical` is `true`, the result is not canonical. Canonically the first digit of the number is always `1` and the sign of the exponent is never omitted. | ||
From version 0.3.0, `.toHexString()` always returns the canonical notation. | ||
````C | ||
printf("%a\n", -57005.7458343505859375); // prints -0x1.bd5b7ddep+15 | ||
````javascript | ||
Math.PI.toString(16); // 3.243f6a8885a3 -> 0x3.243f6a8885a3p0 is valid yet uncanonical | ||
Math.PI.toHexString(); // 0x1.921fb54442d18p+1 is valid and canonical | ||
```` | ||
On the other hand, this implementation takes advangage of the fact `Number.prototype.toString(16)` works for floating point numbers. It just checks the number is negative and prepends '-' if so, then prepend '0x', and append 'p0'. | ||
It seems ok to just prepend '0x' and append 'p0' to `.toString(16)` to make a hex float. Turns out it isn't. It sometimes drops the last bit in some platforms. | ||
````javascript | ||
console.log((-57005.7458343505859375).toHexString()); // -0xdead.beefp0 | ||
console.log((-57005.7458343505859375).toHexString(true)); // -0x1.bd5b7ddep+15 | ||
```` | ||
Math.log(2).toString(16) // 0.b17217f7d1cf78 | ||
Math.log(2).toHexString() // 0x1.62e42fefa39efp-1 | ||
```` | ||
Even when not canonical, you can use the result interchangeably with C99 and other platforms that support the notation (C++11, Ruby, Perl 5.22 ...). | ||
````shell | ||
% perl -E 'say 0x0.b17217f7d1cf78p0 - 0x1.62e42fefa39efp-1' | ||
-1.11022302462516e-16 | ||
% perl -E 'say sprintf "%a", 0x0.b17217f7d1cf78p0 - 0x1.62e42fefa39efp-1' | ||
-0x1p-53 | ||
```` | ||
And `abs(-0x1p-53)` is `DBL_EPSILON`. | ||
## SEE ALSO | ||
@@ -59,0 +67,0 @@ |
@@ -34,8 +34,6 @@ /* | ||
is(parseHexFloat('0xdead.beefp0'), dead_beef)); | ||
it('dead_beef == 0xdead.beefp0', | ||
is((dead_beef).toHexString(), '0xdead.beefp0')); | ||
it('('+dead_beef+').toHexString(true) == 0x1.bd5b7ddep+15', | ||
is((dead_beef).toHexString(true), '0x1.bd5b7ddep+15')); | ||
it('(1/'+dead_beef+')toHexString(true) == 0x1.264eb565bf921p-16', | ||
is((1/dead_beef).toHexString(true), '0x1.264eb565bf921p-16')); | ||
it('('+dead_beef+').toHexString() == 0x1.bd5b7ddep+15', | ||
is((dead_beef).toHexString(), '0x1.bd5b7ddep+15')); | ||
it('(1/'+dead_beef+')toHexString() == 0x1.264eb565bf921p-16', | ||
is((1/dead_beef).toHexString(), '0x1.264eb565bf921p-16')); | ||
it('0xdead.beefp0 == 0x1.bd5b7ddep+15', | ||
@@ -42,0 +40,0 @@ is(parseHexFloat('0xdead.beefp0'), parseHexFloat('0x1.bd5b7ddep+15'))); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
69
14041
91