Skip to content

Commit

Permalink
Fixed #1784
Browse files Browse the repository at this point in the history
  • Loading branch information
ncave authored and alfonsogarciacaro committed Mar 13, 2019
1 parent e782bb4 commit 4274b5d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 27 deletions.
32 changes: 15 additions & 17 deletions src/fable-library/Decimal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ export function toNumber(x: Decimal) {
function decimalToHex(dec: Uint8Array, bitSize: number) {
const hex = new Uint8Array(bitSize / 4 | 0);
let hexCount = 1;
for (const d of dec) {
let val = d;
for (let d = 0; d < dec.length; d++) {
let value = dec[d];
for (let i = 0; i < hexCount; i++) {
const digit = hex[i] * 10 + val | 0;
const digit = hex[i] * 10 + value | 0;
hex[i] = digit & 0xF;
val = digit >> 4;
value = digit >> 4;
}
if (val !== 0) {
hex[hexCount++] = val;
if (value !== 0) {
hex[hexCount++] = value;
}
}
return hex.slice(0, hexCount); // digits in reverse order
Expand All @@ -115,8 +115,8 @@ function decimalToHex(dec: Uint8Array, bitSize: number) {
function hexToDecimal(hex: Uint8Array, bitSize: number) {
const dec = new Uint8Array(bitSize * 301 / 1000 + 1 | 0);
let decCount = 1;
for (const d of hex) {
let carry = d;
for (let d = hex.length - 1; d >= 0; d--) {
let carry = hex[d];
for (let i = 0; i < decCount; i++) {
const val = dec[i] * 16 + carry | 0;
dec[i] = (val % 10) | 0;
Expand Down Expand Up @@ -160,15 +160,13 @@ export function fromParts(low: number, mid: number, high: number, isNegative: bo
setInt32Bits(hexDigits, low, 0);
setInt32Bits(hexDigits, mid, 8);
setInt32Bits(hexDigits, high, 16);
const decDigits = hexToDecimal(hexDigits.reverse(), bitSize);
const sign = isNegative ? "-" : "";
const pos = scale & 0x7F;
let decStr = "";
for (let i = 0; i < decDigits.length; i++) {
if (i === pos) { decStr = "." + decStr; }
decStr = "0123456789".charAt(decDigits[i]) + decStr;
}
const d = new Decimal(sign + decStr);
const decDigits = hexToDecimal(hexDigits, bitSize);
scale = scale & 0x7F;
const big = new Decimal(0);
big.c = Array.from(decDigits.reverse());
big.e = decDigits.length - scale - 1;
big.s = isNegative ? -1 : 1;
const d = new Decimal(big);
return d;
}

Expand Down
26 changes: 17 additions & 9 deletions src/fable-library/lib/big.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ var P = {
* (JavaScript numbers: -7)
* -1000000 is the minimum recommended exponent value of a Big.
*/
NE = -7, // 0 to -1000000
NE = -29, // 0 to -1000000

/*
* The positive exponent (PE) at and above which toString returns exponential notation.
* (JavaScript numbers: 21)
* 1000000 is the maximum recommended exponent value of a Big.
* (This limit is not enforced or checked.)
*/
PE = 21, // 0 to 1000000
PE = 29, // 0 to 1000000


/**************************************************************************************************/
Expand Down Expand Up @@ -345,15 +345,23 @@ P.cmp = function (y) {
// Compare exponents.
if (k != l) return k > l ^ isneg ? 1 : -1;

j = (k = xc.length) < (l = yc.length) ? k : l;

// Compare digit by digit.
for (i = -1; ++i < j;) {
if (xc[i] != yc[i]) return xc[i] > yc[i] ^ isneg ? 1 : -1;
j = Math.max(xc.length, yc.length);
for (i = 0; i < j; i++) {
k = i < xc.length ? xc[i] : 0;
l = i < yc.length ? yc[i] : 0;
if (k != l) return k > l ^ isneg ? 1 : -1;
}

// Compare lengths.
return k == l ? 0 : k > l ^ isneg ? 1 : -1;
return 0;

// old version (doesn't compare well trailing zeroes, e.g. 1.0 with 1.00)
// j = (k = xc.length) < (l = yc.length) ? k : l;
// // Compare digit by digit.
// for (i = -1; ++i < j;) {
// if (xc[i] != yc[i]) return xc[i] > yc[i] ^ isneg ? 1 : -1;
// }
// // Compare lengths.
// return k == l ? 0 : k > l ^ isneg ? 1 : -1;
};


Expand Down
21 changes: 20 additions & 1 deletion tests/Main/ArithmeticTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,32 @@ let tests =
equal (System.Decimal.MaxValue, 79228162514264337593543950335M)
equal (System.Decimal.MinValue, -79228162514264337593543950335M)

testCase "Decimal.ToString works" <| fun () ->
equal (string 001.23456M, "1.23456")
equal (string 1.23456M, "1.23456")
equal (string 0.12345M, "0.12345")
equal (string 0.01234M, "0.01234")
equal (string 0.00123M, "0.00123")
equal (string 0.00012M, "0.00012")
equal (string 0.00001M, "0.00001")
equal (string 0.00000M, "0.00000")
equal (string 0.12300M, "0.12300")
equal (string 0.0M, "0.0")
equal (string 0M, "0")
equal (string 1M, "1")
equal (string -1M, "-1")
equal (string 00000000000000000000000000000.M, "0")
equal (string 0.0000000000000000000000000000M, "0.0000000000000000000000000000")
equal (string 79228162514264337593543950335M, "79228162514264337593543950335")
equal (string -79228162514264337593543950335M, "-79228162514264337593543950335")

testCase "Decimal precision is kept" <| fun () ->
let items = [ 290.8M
290.8M
337.12M
6.08M
-924.8M ]
equal(List.sum items, 0M)
equal (List.sum items, 0M)

testCase "Decimal Infix add can be generated" <| fun () ->
equal (4.0868M + 2.289348M, 6.376148M)
Expand Down

0 comments on commit 4274b5d

Please sign in to comment.