Skip to content

Commit c93ea31

Browse files
authored
Merge pull request #6 from HarrySarson/infinity
Parse and mul functions
2 parents 9664f31 + d791e19 commit c93ea31

File tree

2 files changed

+71
-13
lines changed

2 files changed

+71
-13
lines changed

complex.js

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,16 @@
141141
P['re'] = a['re'];
142142
P['im'] = a['im'];
143143
} else if ('abs' in a && 'arg' in a) {
144+
144145
P['re'] = a['abs'] * Math.cos(a['arg']);
145-
P['im'] = a['abs'] * Math.sin(a['arg']);
146+
P['im'] = a['arg'] === 0
147+
? 0
148+
: a['abs'] * Math.sin(a['arg']);
146149
} else if ('r' in a && 'phi' in a) {
147150
P['re'] = a['r'] * Math.cos(a['phi']);
148-
P['im'] = a['r'] * Math.sin(a['phi']);
151+
P['im'] = a['phi'] === 0
152+
? 0
153+
: a['r'] * Math.sin(a['phi']);
149154
} else {
150155
parser_exit();
151156
}
@@ -154,7 +159,7 @@
154159
case 'string':
155160

156161
P['im'] = /* void */
157-
P['re'] = 0;
162+
P['re'] = 0;
158163

159164
var tokens = a.match(/\d+\.?\d*e[+-]?\d+|\d+\.?\d*|\.\d+|./g);
160165
var plus = 1;
@@ -219,12 +224,51 @@
219224
parser_exit();
220225
}
221226

227+
222228
if (isNaN(P['re']) || isNaN(P['im'])) {
223-
// If a calculation is NaN, we treat it as NaN and don't throw
224-
//parser_exit();
229+
P['re'] = P['im'] = NaN;
230+
}
231+
232+
if (((P['re'] === Infinity || P['re'] === -Infinity) && P['im'] !== 0)
233+
|| ((P['im'] === Infinity || P['im'] === -Infinity) && P['re'] !== 0)) {
234+
P['re'] = P['im'] = Infinity;
225235
}
226236
};
227237

238+
/**
239+
* Convert NaN to zero.
240+
*/
241+
function NaNtoZero(x) {
242+
if (Number.isNaN(x)) {
243+
return 0;
244+
} else {
245+
return x;
246+
}
247+
}
248+
249+
/**
250+
* Test if a complex object `{re, im}` is NaN
251+
*/
252+
function complexIsNaN(z) {
253+
// Todo: is having two checks redundant or sensible?
254+
return isNaN(z['re']) || isNaN(z['im']);
255+
}
256+
257+
/**
258+
* Test if a complex object `{re, im}` is Finite
259+
*/
260+
function complexIsFinte(z) {
261+
return isFinite(z['re']) && isFinite(z['im']);
262+
}
263+
264+
/**
265+
* Test if a complex object `{re, im}` is zero
266+
*/
267+
function complexIsZero(z) {
268+
return z['re'] === 0 && z['im'] === 0;
269+
}
270+
271+
228272
/**
229273
* @constructor
230274
* @returns {Complex}
@@ -297,14 +341,27 @@
297341

298342
parse(a, b); // mutates P
299343

300-
// Besides the addition/subtraction, this helps having a solution for real Infinity
301-
if (P['im'] === 0 && this['im'] === 0) {
302-
return new Complex(this['re'] * P['re'], 0);
344+
/*
345+
* A NaN value is returned if either operand
346+
* is NaN or if one operand is an infinity and
347+
* the other is zero.
348+
*/
349+
350+
if (complexIsNaN(this)
351+
|| complexIsNaN(P)
352+
|| (!complexIsFinte(this) && complexIsZero(P))
353+
|| (!complexIsFinte(P) && complexIsZero(this))
354+
){
355+
return Complex.COMPLEX_NAN;
303356
}
304357

358+
// Some values will be coersed to ComplexNaN by constructor
359+
// make sure not to short cut this parsing.
360+
305361
return new Complex(
306-
this['re'] * P['re'] - this['im'] * P['im'],
307-
this['re'] * P['im'] + this['im'] * P['re']);
362+
NaNtoZero(this['re'] * P['re']) - NaNtoZero(this['im'] * P['im']),
363+
NaNtoZero(this['re'] * P['im']) + NaNtoZero(this['im'] * P['re'])
364+
);
308365
},
309366

310367
/**
@@ -1235,7 +1292,7 @@
12351292
* @returns {boolean}
12361293
*/
12371294
'isNaN': function() {
1238-
return isNaN(this['re']) || isNaN(this['im']);
1295+
return complexIsNaN(this);
12391296
},
12401297

12411298
/**
@@ -1244,7 +1301,7 @@
12441301
* @returns {boolean}
12451302
*/
12461303
'isFinite': function() {
1247-
return isFinite(this['re']) && isFinite(this['im']);
1304+
return complexIsNaN(this);
12481305
},
12491306
};
12501307

@@ -1254,6 +1311,7 @@
12541311
Complex['PI'] = new Complex(Math.PI, 0);
12551312
Complex['E'] = new Complex(Math.E, 0);
12561313
Complex['Infinity'] = new Complex(Infinity, Infinity);
1314+
Complex['NaN'] = new Complex(NaN, NaN);
12571315
Complex['EPSILON'] = 1e-16;
12581316

12591317
if (typeof define === 'function' && define['amd']) {

tests/complex.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ var tests = [{
8080
set: Infinity,
8181
fn: "mul",
8282
param: "i",
83-
expect: "NaN"
83+
expect: "∞i"
8484
}, {
8585
set: "-36i",
8686
fn: "sqrt",

0 commit comments

Comments
 (0)