mirror of
https://github.com/MikeMcl/decimal.js.git
synced 2024-10-27 20:34:12 +00:00
Finally created good test cases, shrunk bitwise code a bit, updated infinite corner cases for or.js, and still having precision problems.
This commit is contained in:
parent
316b416bf4
commit
c0ca644b6b
50
decimal.js
50
decimal.js
@ -831,6 +831,7 @@
|
||||
* n | 0 = n
|
||||
* n | n = n
|
||||
* I | n = I
|
||||
* I | -n = -1
|
||||
* I | I = I
|
||||
* -I | n = -I
|
||||
* -I | -I = -I
|
||||
@ -843,8 +844,9 @@
|
||||
var Decimal = this['constructor'],
|
||||
n = new Decimal(n);
|
||||
|
||||
if (this && n && (!this['c'] || !n['c'])) {
|
||||
if (!this['c'] && !n['c']) {
|
||||
if (this && n && this['s'] && n['s'] && (!this['c'] || !n['c'])) {
|
||||
if ((!this['c'] && this['s'] > 0 && n['lt'](0)) || (this['lt'](0) && n['s'] > 0 && !n['c']) ||
|
||||
this['eq'](-1) || n['eq'](-1)) {
|
||||
return new Decimal(-1);
|
||||
}
|
||||
return new Decimal(this['c'] ? n : this);
|
||||
@ -2049,49 +2051,49 @@
|
||||
return new Decimal(NaN);
|
||||
}
|
||||
|
||||
var xBits, yBits, tmpExternal = external;
|
||||
var tmpExternal = external;
|
||||
external = false;
|
||||
if (x['s'] < 0) {
|
||||
xBits = '1' + x['not']()['toString'](2).replace(/[01]/g, function (d) { return +!+d });
|
||||
|
||||
var xBits, yBits,
|
||||
xTrunc = x['trunc'](),
|
||||
yTrunc = y['trunc'](),
|
||||
xLtZero = xTrunc['lt'](0),
|
||||
yLtZero = yTrunc['lt'](0);
|
||||
|
||||
if (xLtZero) {
|
||||
xBits = '1' + xTrunc['not']()['toString'](2).replace(/[01]/g, function (d) { return +!+d });
|
||||
} else {
|
||||
xBits = '0' + x['trunc']()['toString'](2);
|
||||
xBits = '0' + xTrunc['toString'](2);
|
||||
}
|
||||
|
||||
if (y['s'] < 0) {
|
||||
yBits = '1' + y['not']()['toString'](2).replace(/[01]/g, function (d) { return +!+d });
|
||||
if (yLtZero) {
|
||||
yBits = '1' + yTrunc['not']()['toString'](2).replace(/[01]/g, function (d) { return +!+d });
|
||||
} else {
|
||||
yBits = '0' + y['trunc']()['toString'](2);
|
||||
yBits = '0' + yTrunc['toString'](2);
|
||||
}
|
||||
external = tmpExternal;
|
||||
|
||||
if (xBits.length > yBits.length) {
|
||||
yBits = yBits.padLeft((y['s'] < 0) ? '1' : '0', xBits.length);
|
||||
yBits = yBits.padLeft(yLtZero ? '1' : '0', xBits.length);
|
||||
} else if (xBits.length < yBits.length) {
|
||||
xBits = xBits.padLeft((x['s'] < 0) ? '1' : '0', yBits.length);
|
||||
xBits = xBits.padLeft(xLtZero ? '1' : '0', yBits.length);
|
||||
}
|
||||
|
||||
|
||||
var outVal = new Decimal(0);
|
||||
var twoPower = Decimal['ONE'];
|
||||
if (func(xBits[0], yBits[0]) == 0) {
|
||||
var expFuncVal = func(xBits[0], yBits[0]) ^ 1;
|
||||
for (var i = xBits.length - 1; i > 0; --i) {
|
||||
if (func(xBits[i], yBits[i])) {
|
||||
if (func(xBits[i], yBits[i]) == expFuncVal) {
|
||||
outVal = outVal['plus'](twoPower);
|
||||
}
|
||||
twoPower = twoPower['times'](2);
|
||||
}
|
||||
if (expFuncVal == 0) {
|
||||
outVal = outVal['plus'](Decimal['ONE'])['neg']();
|
||||
}
|
||||
external = tmpExternal;
|
||||
return outVal;
|
||||
}
|
||||
|
||||
for (var i = xBits.length - 1; i > 0; --i) {
|
||||
if (func(xBits[i], yBits[i]) == 0) {
|
||||
outVal = outVal['plus'](twoPower['plus'](Decimal['ONE']));
|
||||
}
|
||||
twoPower = twoPower['times'](2);
|
||||
}
|
||||
return outVal['plus'](Decimal['ONE'])['neg']();
|
||||
}
|
||||
|
||||
function coefficientToString(a) {
|
||||
var s, z,
|
||||
i = 1,
|
||||
|
204647
test/or.js
204647
test/or.js
File diff suppressed because it is too large
Load Diff
208
test/or.py
Normal file
208
test/or.py
Normal file
@ -0,0 +1,208 @@
|
||||
import random
|
||||
from decimal import *
|
||||
|
||||
header_str = """var count = (function plus(Decimal) {
|
||||
var start = +new Date(),
|
||||
log,
|
||||
error,
|
||||
undefined,
|
||||
passed = 0,
|
||||
total = 0,
|
||||
n = 'null',
|
||||
N = 'NaN',
|
||||
I = 'Infinity';
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
log = console.log;
|
||||
error = console.error;
|
||||
} else {
|
||||
log = function (str) { document.body.innerHTML += str.replace('\\n', '<br>') };
|
||||
error = function (str) { document.body.innerHTML += '<div style="color: red">' +
|
||||
str.replace('\\n', '<br>') + '</div>' };
|
||||
}
|
||||
|
||||
if (!Decimal && typeof require === 'function') Decimal = require('../decimal');
|
||||
|
||||
function assert(expected, actual) {
|
||||
total++;
|
||||
if (expected !== actual) {
|
||||
error('\\n Test number: ' + total + ' failed');
|
||||
error(' Expected: ' + expected);
|
||||
error(' Actual: ' + actual);
|
||||
//process.exit();
|
||||
} else {
|
||||
passed++;
|
||||
//log('\\n Expected and actual: ' + actual);
|
||||
}
|
||||
}
|
||||
|
||||
function T(orendA, orendB, expected, sd, rm) {
|
||||
|
||||
if ( sd != null ) {
|
||||
Decimal.precision = sd;
|
||||
Decimal.rounding = rm;
|
||||
}
|
||||
assert(String(expected), String(new Decimal(orendA).or(orendB)));
|
||||
}
|
||||
|
||||
log('\\n Testing or...');
|
||||
|
||||
Decimal.config({
|
||||
precision: 20,
|
||||
rounding: 4,
|
||||
toExpNeg: -9e15,
|
||||
toExpPos: 9e15,
|
||||
minE: -9e15,
|
||||
maxE: 9e15,
|
||||
errors: false
|
||||
});
|
||||
|
||||
T(1, 0, 1);
|
||||
T(1, -0, 1);
|
||||
T(-1, 0, -1);
|
||||
T(-1, -0, -1);
|
||||
T(1, N, N);
|
||||
T(-1, N, N);
|
||||
T(1, I, I);
|
||||
T(1, -I, -I);
|
||||
T(-1, I, -1);
|
||||
T(-1, -I, -1);
|
||||
T(0, 1, 1);
|
||||
T(0, -1, -1);
|
||||
T(-0, 1, 1);
|
||||
T(-0, -1, -1);
|
||||
|
||||
T(0, N, N);
|
||||
T(-0, N, N);
|
||||
T(0, I, I);
|
||||
T(0, -I, -I);
|
||||
T(-0, I, I);
|
||||
T(-0, -I, -I);
|
||||
T(N, 1, N);
|
||||
T(N, -1, N);
|
||||
T(N, 0, N);
|
||||
T(N, -0, N);
|
||||
T(N, N, N);
|
||||
T(N, I, N);
|
||||
T(N, -I, N);
|
||||
T(I, 1, I);
|
||||
T(I, -1, -1);
|
||||
T(-I, 1, -I);
|
||||
T(-I, -1, -1);
|
||||
T(I, 0, I);
|
||||
T(I, -0, I);
|
||||
T(-I, 0, -I);
|
||||
T(-I, -0, -I);
|
||||
T(I, N, N);
|
||||
T(-I, N, N);
|
||||
T(I, I, I);
|
||||
T(I, -I, -1);
|
||||
T(-I, I, -1);
|
||||
T(-I, -I, -I);
|
||||
|
||||
T(1, '0', '1');
|
||||
T(1, '1', '1');
|
||||
T(1, '-45', '-45');
|
||||
T(1, '22', '23');
|
||||
T(1, '0144', '145');
|
||||
T(1, '6.1915', '7');
|
||||
T(1, '-1.02', '-1');
|
||||
|
||||
"""
|
||||
|
||||
modes = [
|
||||
'ROUND_UP',
|
||||
'ROUND_DOWN',
|
||||
'ROUND_CEILING',
|
||||
'ROUND_FLOOR',
|
||||
'ROUND_HALF_UP',
|
||||
'ROUND_HALF_DOWN',
|
||||
'ROUND_HALF_EVEN',
|
||||
'ROUND_05UP'
|
||||
]
|
||||
|
||||
def getRand(i,d):
|
||||
return Decimal('%d.%0*d' % (random.randint(0, 10**i-1), d, random.randint(0, 10**d-1)))
|
||||
|
||||
def getRandExp(max_digits=20, max_exp=3):
|
||||
s = '' if random.randint(1, 2) == 1 else '-'
|
||||
s += str(random.randint(1, 9)) + '.'
|
||||
|
||||
for i in range(random.randint(0, max_digits - 1)):
|
||||
s += str(random.randint(0, 9))
|
||||
|
||||
s += 'e-' if random.randint(1, 4) == 1 else 'e+'
|
||||
|
||||
for i in range(random.randint(1, max_exp)):
|
||||
s += str(random.randint(0, 9))
|
||||
|
||||
try:
|
||||
d = Decimal(s)
|
||||
except Exception, e:
|
||||
d = getRandExp(max_digits, max_exp)
|
||||
|
||||
return d
|
||||
|
||||
def sci_str(dec):
|
||||
return ('{:.' + str(len(str(dec)) - 1) + 'e}').format(dec)
|
||||
|
||||
file = open('or.js', 'w')
|
||||
file.write(header_str + '\n')
|
||||
|
||||
|
||||
ctx = getcontext()
|
||||
ctx.Emax = 9000000000000000
|
||||
ctx.Emin = -9000000000000000
|
||||
max = Decimal('9.9e+300')
|
||||
min = Decimal('-9.9e300')
|
||||
i = 0
|
||||
biggest = Decimal('0')
|
||||
|
||||
while i < 200000:
|
||||
x = getRandExp()
|
||||
y = getRandExp()
|
||||
|
||||
if ((x < min or x > max or x == Decimal('0')) or
|
||||
(y < min or y > max or y == Decimal('0'))):
|
||||
continue
|
||||
|
||||
# Maximum precision of result.
|
||||
pr = random.randint(1, 100)
|
||||
|
||||
# Rounding mode
|
||||
rm = random.randint(0, 6)
|
||||
result_rm = modes[rm]
|
||||
|
||||
ctx.prec = pr
|
||||
ctx.rounding = result_rm
|
||||
|
||||
try:
|
||||
result = Decimal(int(x) | int(y))
|
||||
except Exception, e:
|
||||
print(e.message)
|
||||
print( str(i) + ': sqrt(' + str(x) + ')' )
|
||||
continue
|
||||
|
||||
if result < min or result > max or result == Decimal('0') or result == Decimal('1'):
|
||||
continue
|
||||
|
||||
result = ( " T('" + str(x) + "', '" + str(y) + "', '" + str(result) + "', " + str(pr) + ", " + str(rm) + ");\n" )
|
||||
|
||||
if x > biggest:
|
||||
biggest = x
|
||||
|
||||
if i % 100 == 0:
|
||||
print(i)
|
||||
|
||||
file.write(result)
|
||||
#print(result)
|
||||
|
||||
i += 1
|
||||
|
||||
print('biggest: ' + sci_str(biggest))
|
||||
file.write("""
|
||||
log('\\n ' + passed + ' of ' + total + ' tests passed in ' + (+new Date() - start) + ' ms \\n');
|
||||
return [passed, total];
|
||||
})(this.Decimal);
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = count;""")
|
||||
file.close()
|
10093
test/testGen.py
10093
test/testGen.py
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user