Skip to content

Commit

Permalink
Merge pull request #95 from christianp/issue-94
Browse files Browse the repository at this point in the history
  • Loading branch information
gentooboontoo committed Dec 15, 2018
2 parents 90caffc + e0c2a22 commit cb3540b
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 46 deletions.
46 changes: 46 additions & 0 deletions spec/quantitiesSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,32 @@ describe("js-quantities", function() {
expect(result.units()).toBe("");
});

it("should multiply quantities and their inverses with prefixes", function() {
var qty1 = Qty("3m");
var qty2 = Qty("4 1/km");
var result = qty1.mul(qty2);
expect(result.scalar).toBe(0.012);
expect(result.isUnitless()).toBe(true);

qty1 = Qty("3 A/km");
qty2 = Qty("4 m");
result = qty1.mul(qty2);
expect(result.scalar).toBe(0.012);
expect(result.units()).toBe("A");

qty1 = Qty("3 1/km2");
qty2 = Qty("4 m");
result = qty1.mul(qty2);
expect(result.scalar).toBe(0.012);
expect(result.units()).toBe("1/km");

qty1 = Qty("4 m");
qty2 = Qty("3 1/km2");
result = qty1.mul(qty2);
expect(result.scalar).toBe(0.000012);
expect(result.units()).toBe("1/m");
});

it("should divide quantities", function() {
var qty1 = Qty("2.5m");
var qty2 = Qty("3m");
Expand Down Expand Up @@ -840,6 +866,26 @@ describe("js-quantities", function() {
expect(result.units()).toBe("1/S2");
});

it("should divide quantities and their inverses with prefixes", function() {
var qty1 = Qty("3m*A");
var qty2 = Qty("4 km");
var result = qty1.div(qty2);
expect(result.scalar).toBe(0.00075);
expect(result.units()).toBe("A");

qty1 = Qty("3 m");
qty2 = Qty("4 km*A");
result = qty1.div(qty2);
expect(result.scalar).toBe(0.00075);
expect(result.units()).toBe("1/A");

qty1 = Qty("3 m");
qty2 = Qty("4 km*cA");
result = qty1.div(qty2);
expect(result.scalar).toBe(0.00075);
expect(result.units()).toBe("1/cA");
});

});

describe("math with temperatures", function() {
Expand Down
93 changes: 47 additions & 46 deletions src/quantities/operators.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Qty from "./constructor.js";
import QtyError, { throwIncompatibleUnits } from "./error.js";
import { PREFIX_VALUES, UNITY, UNITY_ARRAY } from "./definitions.js";
import { assign, isNumber, isString, mulSafe } from "./utils.js";
import { assign, isNumber, isString, mulSafe, divSafe } from "./utils.js";
import {
addTempDegrees,
subtractTempDegrees,
Expand Down Expand Up @@ -75,9 +75,9 @@ assign(Qty.prototype, {
if (op1.isCompatible(op2) && op1.signature !== 400) {
op2 = op2.to(op1);
}
var numden = cleanTerms(op1.numerator.concat(op2.numerator), op1.denominator.concat(op2.denominator));
var numdenscale = cleanTerms(op1.numerator, op1.denominator, op2.numerator, op2.denominator);

return Qty({"scalar": mulSafe(op1.scalar, op2.scalar), "numerator": numden[0], "denominator": numden[1]});
return Qty({"scalar": mulSafe(op1.scalar, op2.scalar, numdenscale[2]), "numerator": numdenscale[0], "denominator": numdenscale[1]});
},

div: function(other) {
Expand Down Expand Up @@ -111,9 +111,9 @@ assign(Qty.prototype, {
if (op1.isCompatible(op2) && op1.signature !== 400) {
op2 = op2.to(op1);
}
var numden = cleanTerms(op1.numerator.concat(op2.denominator), op1.denominator.concat(op2.numerator));
var numdenscale = cleanTerms(op1.numerator, op1.denominator, op2.denominator, op2.numerator);

return Qty({"scalar": op1.scalar / op2.scalar, "numerator": numden[0], "denominator": numden[1]});
return Qty({"scalar": mulSafe(op1.scalar, numdenscale[2]) / op2.scalar, "numerator": numdenscale[0], "denominator": numdenscale[1]});
},

// Returns a Qty that is the inverse of this Qty,
Expand All @@ -128,70 +128,71 @@ assign(Qty.prototype, {
}
});

function cleanTerms(num, den) {
num = num.filter(function(val) {
function cleanTerms(num1, den1, num2, den2) {
function notUnity(val) {
return val !== UNITY;
});
den = den.filter(function(val) {
return val !== UNITY;
});
}

num1 = num1.filter(notUnity);
num2 = num2.filter(notUnity);
den1 = den1.filter(notUnity);
den2 = den2.filter(notUnity);

var combined = {};

var k;
for (var i = 0; i < num.length; i++) {
if (PREFIX_VALUES[num[i]]) {
k = [num[i], num[i + 1]];
i++;
}
else {
k = num[i];
}
if (k && k !== UNITY) {
if (combined[k]) {
combined[k][0]++;
function combineTerms(terms, direction) {
var k;
var prefix;
var prefixValue;
for (var i = 0; i < terms.length; i++) {
if (PREFIX_VALUES[terms[i]]) {
k = terms[i + 1];
prefix = terms[i];
prefixValue = PREFIX_VALUES[prefix];
i++;
}
else {
combined[k] = [1, k];
k = terms[i];
prefix = null;
prefixValue = 1;
}
}
}

for (var j = 0; j < den.length; j++) {
if (PREFIX_VALUES[den[j]]) {
k = [den[j], den[j + 1]];
j++;
}
else {
k = den[j];
}
if (k && k !== UNITY) {
if (combined[k]) {
combined[k][0]--;
}
else {
combined[k] = [-1, k];
if (k && k !== UNITY) {
if (combined[k]) {
combined[k][0] += direction;
var combinedPrefixValue = combined[k][2] ? PREFIX_VALUES[combined[k][2]] : 1;
combined[k][direction === 1 ? 3 : 4] *= divSafe(prefixValue, combinedPrefixValue);
}
else {
combined[k] = [direction, k, prefix, 1, 1];
}
}
}
}

num = [];
den = [];
combineTerms(num1, 1);
combineTerms(den1, -1);
combineTerms(num2, 1);
combineTerms(den2, -1);

var num = [];
var den = [];
var scale = 1;

for (var prop in combined) {
if (combined.hasOwnProperty(prop)) {
var item = combined[prop];
var n;
if (item[0] > 0) {
for (n = 0; n < item[0]; n++) {
num.push(item[1]);
num.push(item[2] === null ? item[1] : [item[2], item[1]]);
}
}
else if (item[0] < 0) {
for (n = 0; n < -item[0]; n++) {
den.push(item[1]);
den.push(item[2] === null ? item[1] : [item[2], item[1]]);
}
}
scale *= divSafe(item[3], item[4]);
}
}

Expand All @@ -210,5 +211,5 @@ function cleanTerms(num, den) {
return a.concat(b);
}, []);

return [num, den];
return [num, den, scale];
}

0 comments on commit cb3540b

Please sign in to comment.