@lhncbc/ucum-lhc 6.0.2 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/source/unit.js CHANGED
@@ -393,7 +393,7 @@ export class Unit {
393
393
  // reject request if both units have dimensions that are not equal
394
394
  if (fromUnit.dim_ && this.dim_ && !(fromUnit.dim_.equals(this.dim_))) {
395
395
  // check first to see if a mole<->mass conversion is appropriate
396
- if (this.isMoleMassCommensurable(fromUnit)) {
396
+ if (this.isMolMassCommensurable(fromUnit)) {
397
397
  throw(new Error(Ucum.needMoleWeightMsg_));
398
398
  }
399
399
  else {
@@ -524,116 +524,121 @@ export class Unit {
524
524
 
525
525
 
526
526
  /**
527
- * Calculates the number of units that would result from converting a unit
528
- * expressed in mass/grams to a unit expressed in moles. The "this" unit is
529
- * the unit expressed in some form of mass (g, mg, mmg, kg, whatever) and the
530
- * target or "to" unit - the molUnit parameter - is a unit expressed in moles
531
- * - mol, umol, mmol, etc. The unit expressions surrounding the moles and
532
- * mass must be convertible. No validation of this requirement is performed.
533
- *
534
- * @param amt the quantity of this unit to be converted
535
- * @param molUnit the target/to unit for which the converted # is wanted
536
- * @param molecularWeight the molecular weight of the substance for which the
537
- * conversion is being made
538
- * @return the equivalent amount in molUnit
539
- */
540
- convertMassToMol(amt, molUnit, molecularWeight) {
541
- // The prefix values that have been applied to this unit, which is the mass
542
- // (grams) unit, are reflected in the magnitude. So the number of moles
543
- // represented by this unit equals the number of grams -- amount * magnitude
544
- // divided by the molecular Weight
545
- let molAmt = (this.magnitude_ * amt)/molecularWeight ;
546
- // The molUnit's basic magnitude, before prefixes are applied,
547
- // is avogadro's number, get that and divide it out of the current magnitude.
548
- let tabs = this._getUnitTables();
549
- let avoNum = tabs.getUnitByCode('mol').magnitude_ ;
550
- let molesFactor = molUnit.magnitude_ / avoNum ;
551
- // return the molAmt divided by the molesFactor as the number of moles
552
- // for the molUnit
553
- return molAmt/molesFactor ;
554
- } // end convertMassToMol
555
-
556
- /**
557
- * Calculates the number of units that would result from converting a unit
558
- * expressed in moles to a unit expressed in mass (grams). The "this" unit
559
- * is the unit expressed in some form of moles, e.g., mol, umol, mmol, etc.,
560
- * and the target or "to" unit is a unit expressed in some form of mass, e.g.,
561
- * g, mg, mmg, kg, etc. Any unit expressions surrounding the moles and mass
562
- * must be convertible. No validation of this requirement is performed.
563
- *
527
+ * This function converts between mol and mass (in either direction)
528
+ * using the molecular weight of the substance. It assumes that the
529
+ * isMolMassCommensurable" function has been called to check that the units are
530
+ * commensurable.
531
+ *
564
532
  * @param amt the quantity of this unit to be converted
565
- * @param massUnit the target/to unit for which the converted # is wanted
533
+ * @param toUnit the target/to unit for which the converted # is wanted
566
534
  * @param molecularWeight the molecular weight of the substance for which the
567
535
  * conversion is being made
568
- * @return the equivalent amount in massUnit
536
+ * @return the equivalent amount in toUnit
569
537
  */
570
- convertMolToMass(amt, massUnit, molecularWeight) {
538
+ convertMolMass(amt, toUnit, molecularWeight) {
539
+ // In the calculations below we are treating "molecularWeight" (measured in
540
+ // a.m.u) as the molar weight (measured in g/mol). The values are the same,
541
+ // though the units differ.
542
+
543
+ // Determine the number of powers of mol we have to convert to mass.
544
+ // Typically this will be just 1, or -1, but not necessarily. If it is a
545
+ // negative number, then we are really converting mass to moles.
546
+ const molPowersToConvert = this.moleExp_ - toUnit.moleExp_;
571
547
  // A simple mole unit has a magnitude of avogadro's number. Get that
572
548
  // number now (since not everyone agrees on what it is, and what is
573
549
  // being used in this system might change).
574
550
  let tabs = this._getUnitTables();
575
551
  let avoNum = tabs.getUnitByCode('mol').magnitude_ ;
576
- // Determine what prefix values (mg or mg/dL, etc.) have been applied to
577
- // this unit by dividing the simple mole unit magnitude out of the
578
- // current mole unit magnitude.
579
- let molesFactor = this.magnitude_ / avoNum ;
580
- // The number of grams (mass) is equal to the number of moles (amt)
581
- // times the molecular weight. We also multiply that by the prefix values
582
- // applied to the current unit (molesFactor) to get the grams for this
583
- // particular unit.
584
- let massAmt = (molesFactor * amt) * molecularWeight ;
585
- // Finally, we return the mass amount/grams for this particular unit
586
- // divided by any effects of prefixes applied to the "to" unit, which
587
- // is assumed to be some form of a gram unit
588
- return massAmt / massUnit.magnitude_ ;
589
- } // end convertMolToMass
552
+ // For each molPowersToConvert, we need to multiply the mol unit by the
553
+ // molar weight (g/mol) and divide by avoNum (1/mol) to get a weight per
554
+ // molecule. (Note that the magnitude_ of each unit will contain factors of
555
+ // avoNum, of which we are thus getting rid of some).
556
+ let moleUnitFactor = Math.pow(molecularWeight/avoNum, molPowersToConvert);
557
+ // The new value is proportional to this.magnitude_, amt, and
558
+ // moleUnitFactor, and inversely proportional to toUnit_.magnitude.
559
+ return this.magnitude_/toUnit.magnitude_ * moleUnitFactor * amt;
560
+ } // end convertMolMass
561
+
590
562
 
591
563
  /**
592
- * Converts equivalents to mass.
593
- *
594
- * @param {number} equivalents - The amount in equivalents to be converted.
595
- * @param {object} targetUnit - The target/to unit for which the converted number is wanted.
596
- * @param {number} molecularWeight - The molecular weight of the substance for which the conversion is being made.
597
- * @param {number} charge - The absolute value of the charge of the substance for which the conversion is being made.
598
- * @returns {number} - The equivalent mass in the specified mass unit.
599
- */
600
- convertEqToMass(equivalents, targetUnit, molecularWeight, charge) {
601
- let standardMoleUnit = this._getUnitTables().getUnitByCode('mol');
602
- const molAmount = this.convertEqToMol(equivalents, standardMoleUnit, charge);
603
- return this.convertMolToMass(molAmount, targetUnit, molecularWeight);
604
- } // end convertEqToMass
605
-
606
- /**
607
- * Converts mass to equivalents.
608
- *
609
- * @param {number} mass - The mass to be converted.
610
- * @param {object} eqUnit - The target/to unit for which the converted number is wanted.
564
+ * This function converts between equivalants and mass (in either direction)
565
+ * using the charge of the substance. It assumes that the
566
+ * isEqMassCommensurable" function has been called to check that the units are
567
+ * commensurable.
568
+ *
569
+ * @param {number} amt - The amount of this unit to be converted.
570
+ * @param {object} toUnit - The target/to unit for which the converted number is wanted.
611
571
  * @param {number} molecularWeight - The molecular weight of the substance for which the conversion is being made.
612
572
  * @param {number} charge - The absolute value of the charge of the substance for which the conversion is being made.
613
- * @returns {number} - The equivalent amount in the specified equivalent unit.
573
+ * @returns {number} - The amount in the specified toUnit.
614
574
  */
615
- convertMassToEq(mass, eqUnit, molecularWeight, charge) {
575
+ convertEqMass(amt, toUnit, molecularWeight, charge) {
576
+ // Determine the number of powers of mass we have to convert to equivalents.
577
+ // Typically this will be just 1, or -1, but not necessarily. If it is a
578
+ // negative number, then we are converting in the opposite direciton.
579
+ // Because the units are presumed commensurable, we can use the
580
+ // equivalentExp_ instead of the mass dimension.
581
+ const massPowersToConvert = toUnit.equivalentExp_ - this.equivalentExp_ ;
616
582
  // Calculate equivalent mass by dividing molecular weight by charge
617
583
  let equivalentMass = molecularWeight / charge;
618
- // Calculate equivalents by dividing mass by equivalent mass
619
- let equivalents = mass / equivalentMass;
620
584
  // Get Avogadro's number from the unit tables
621
585
  let avogadroNumber = this._getUnitTables().getUnitByCode('mol').magnitude_ ;
622
- // Calculate mole factor by dividing the magnitude of the equivalent unit by Avogadro's number
623
- // eqUnit may have a prefix (e.g. meq) and we need to adjust for that
624
- let moleFactor = eqUnit.magnitude_ / avogadroNumber ;
586
+ // Calculate equivalents by dividing mass by equivalent mass, for each
587
+ // power to be converted.
588
+ let equivalents = this.magnitude_ * amt / Math.pow(equivalentMass, massPowersToConvert);
589
+ // Calculate mole factor by dividing the magnitude of the equivalent unit by
590
+ // Avogadro's number. toUnit may have a prefix (e.g. meq) and we need to adjust for that, for
591
+ // each massPowersToConvert.
592
+ let moleFactor = toUnit.magnitude_ / Math.pow(avogadroNumber, massPowersToConvert);
625
593
  // Adjust equivalents by dividing by the mole factor
626
594
  let adjustedEquivalents = equivalents / moleFactor;
627
595
  // Return the adjusted equivalents
628
596
  return adjustedEquivalents;
629
597
  } // end convertMassToEq
630
598
 
599
+
600
+ /**
601
+ * Converts a unit with eq/mol/mass to another unit with eq/mol/mass. It
602
+ * assumes the units an commensurable, which can be checked via
603
+ * isEqMolMassCommensurable. It also assumes that the powers of eq/mol/mass
604
+ * are different between the two units; otherwise it would be more efficient
605
+ * to call one of the other convert... functions.
606
+ *
607
+ * @param {number} amt - The amount of this unit to be converted.
608
+ * @param {object} toUnit - The target/to unit for which the converted number is wanted.
609
+ * @param {number} molecularWeight - The molecular weight of the substance for which the conversion is being made.
610
+ * @param {number} charge - The absolute value of the charge of the substance for which the conversion is being made.
611
+ * @returns {number} - The equivalent amount in the specified equivalent unit.
612
+ */
613
+ convertEqMolMass(amt, toUnit, molecularWeight, charge) {
614
+ // Handle the equivalent differences. It important for the following
615
+ // calculations (for consistency) that we consider the difference in
616
+ // equivalent powers and not mol powers, so we are not calling
617
+ // convertEqToMol, in case its implementation changes.
618
+ // See convertEqToMol for details. One difference is that we do not scale
619
+ // by magnitude_ until the end.
620
+ const eqPowersToConvert = this.equivalentExp_ - toUnit.equivalentExp_;
621
+ const molAmt = amt / Math.pow(charge, eqPowersToConvert);
622
+ // Now for the mol/mass converstion part, we consider only the mass power
623
+ // differences, and not the mol power differences (which were partially
624
+ // handled in the eq/mol step above).
625
+ // Again, see convertMolToMass for details on the calculations.
626
+ const tabs = this._getUnitTables();
627
+ const d = tabs.getMassDimensionIndex();
628
+ const massPowersToConvert = this.dim_.getElementAt(d) - toUnit.dim_.getElementAt(d);
629
+ const molPowersToConvert = -massPowersToConvert; // so the formulas follow convertMolToMass
630
+ const avoNum = tabs.getUnitByCode('mol').magnitude_ ;
631
+ let moleUnitFactor = Math.pow(molecularWeight/avoNum, molPowersToConvert);
632
+ return this.magnitude_/toUnit.magnitude_ * moleUnitFactor * molAmt;
633
+ }
634
+
635
+
631
636
  /**
632
637
  * Checks if the given unit is an equivalent unit.
633
- *
634
- * Note: equivalent units are also be molar units, so a unit can return true for
638
+ *
639
+ * Note: equivalent units are also be molar units, so a unit can return true for
635
640
  * both isEquivalentUnit and isMolarUnit.
636
- *
641
+ *
637
642
  * @returns {boolean} - Returns true if the unit is an equivalent unit, false otherwise.
638
643
  */
639
644
  isEquivalentUnit() {
@@ -642,7 +647,7 @@ export class Unit {
642
647
 
643
648
  /**
644
649
  * Checks if the given unit is a molar unit.
645
- *
650
+ *
646
651
  * @returns {boolean} - Returns true if the unit is a molar unit, false otherwise.
647
652
  */
648
653
  isMolarUnit() {
@@ -651,41 +656,39 @@ export class Unit {
651
656
 
652
657
 
653
658
  /**
654
- * This function converts an equivalent amount to moles using the charge of the substance.
655
- *
656
- * @param {number} eqFromVal - The equivalent amount for which the conversion is being made.
657
- * @param {object} molToUnit - The target unit for which the converted number is wanted.
659
+ * This function converts between equivalants and moles (in either direction)
660
+ * using the charge of the substance. It assumes that the
661
+ * isEqMolCommensurable" function has been called to check that the units are
662
+ * commensurable.
663
+
664
+ * As with the other "convert" functions, it assumes the appropriate
665
+ * "is...Commensurable" function has been called.
666
+ *
667
+ * @param {number} amt - The amount of this unit for which the conversion is being made.
668
+ * @param {object} toUnit - The target unit for which the converted number is wanted.
658
669
  * @param {number} charge - The absolute value of the charge of the substance for which the conversion is being made.
659
- * @return {number} - The amount in moles.
670
+ * @return {number} - The amount in molToUnit.
660
671
  */
661
- convertEqToMol(eqFromVal, molToUnit, charge){
662
- // Check if molToUnit is a molar unit and eqFromVal is a eq unit
663
- if (!molToUnit.isMolarUnit() || !this.isEquivalentUnit()){
664
- throw new Error("Invalid units for conversion of Eq to Mol. Please provide an equivalent and a molar unit.");
665
- }
666
- // The conversion from equivalents to moles is based on the principle that one equivalent is equal to 1/valencyFactor moles.
667
- // The relative magnitude is accounted for via the current unit's magnitude (this.magnitude_) and the target unit's magnitude (molToUnit.magnitude_)
668
- return eqFromVal * (this.magnitude_ / molToUnit.magnitude_) / charge;
669
- } // end convertEqToMol
672
+ convertEqMol(amt, toUnit, charge) {
673
+ // Determine the number of powers of eq we have to convert to mol.
674
+ // Typically this will be just 1, or -1, but not necessarily. If it is a
675
+ // negative number, then we are really converting mol to eq.
676
+ const eqPowersToConvert = this.equivalentExp_ - toUnit.equivalentExp_;
677
+
678
+ // A simple mole unit has a magnitude of avogadro's number.
679
+ // So does 'eq' (equivalent) because in ucum it is defined as 1 mol, though
680
+ // that does not account for the charge. Therefore, we don't need to
681
+ // account for that factor in this conversion.
682
+
683
+ // The conversion from equivalents to moles is based on the principle that
684
+ // one equivalent is equal to 1/charge moles (per eqPowersToConvert).
685
+ // The relative magnitude is accounted for via the current unit's magnitude
686
+ // (this.magnitude_) and the target unit's magnitude (molToUnit.magnitude_)
687
+ // For each eqPowersToConvert, we need to divide by the charge.
688
+ return amt * (this.magnitude_ / toUnit.magnitude_) / Math.pow(charge, eqPowersToConvert);
689
+ } // end convertEqMol
690
+
670
691
 
671
- /**
672
- * This function converts moles to equivalent amount using the charge of the substance.
673
- *
674
- * @param {number} molFromVal - The mole amount for which the conversion is being made
675
- * @param {object} eqToUnit - The target unit for which the converted number is wanted
676
- * @param {number} charge - The absolute value of the charge of the substance for which the conversion is being made
677
- * @return {number} - The amount in equivalent
678
- */
679
- convertMolToEq(molFromVal, eqToUnit, charge){
680
- // Check if eqToUnit is an equivalent unit and molFromVal is a molar unit
681
- if (!eqToUnit.isEquivalentUnit() || !this.isMolarUnit()){
682
- throw new Error("Invalid units for conversion of Mol to Eq. Please provide a molar and an equivalent unit.");
683
- }
684
- // The conversion from moles to equivalents is based on the principle that one equivalent is equal to 1/valencyFactor moles.
685
- // The relative magnitude is accounted for via the current unit's magnitude (this.magnitude_) and the target unit's magnitude (eqToUnit.magnitude_)
686
- return molFromVal * charge * (this.magnitude_ / eqToUnit.magnitude_);
687
- } // end convertMolToEq
688
-
689
692
  /**
690
693
  * Mutates this unit into a unit on a ratio scale and converts a specified
691
694
  * number of units to an appropriate value for this converted unit
@@ -783,6 +786,10 @@ export class Unit {
783
786
  retUnit.dim_.add(unit2.dim_);
784
787
  }
785
788
 
789
+ // Add the values of equivalentExp_ and moleExp for the two units
790
+ retUnit.equivalentExp_ += unit2.equivalentExp_;
791
+ retUnit.moleExp_ += unit2.moleExp_;
792
+
786
793
  // Concatenate the unit info (name, code, etc) for all cases
787
794
  // where the multiplication was performed (an error wasn't thrown)
788
795
  retUnit.name_ = this._concatStrs(retUnit.name_, '*', unit2.name_, '[', ']');
@@ -800,10 +807,6 @@ export class Unit {
800
807
  else if (unit2.printSymbol_)
801
808
  retUnit.printSymbol_ = unit2.printSymbol_;
802
809
 
803
- // Update the mole exponent count by adding the count for unit2 to the
804
- // count for this unit.
805
- retUnit.moleExp_ = retUnit.moleExp_ + unit2.moleExp_ ;
806
-
807
810
  // A unit that has the arbitrary attribute taints any unit created from it
808
811
  // via an arithmetic operation. Taint accordingly
809
812
  // if (!retUnit.isMole_)
@@ -892,8 +895,10 @@ export class Unit {
892
895
  } // end if unit2 has a dimension object
893
896
 
894
897
  // Update the mole exponent count by subtracting the count for unit2 from
895
- // the // count for this unit.
896
- retUnit.moleExp_ = retUnit.moleExp_ - unit2.moleExp_ ;
898
+ // the count for this unit.
899
+ retUnit.moleExp_ -= unit2.moleExp_ ;
900
+ // Also update the equivalent exponent.
901
+ retUnit.equivalentExp_ -= unit2.equivalentExp_;
897
902
 
898
903
  // A unit that has the arbitrary attribute taints any unit created from
899
904
  // it via an arithmetic operation. Taint accordingly
@@ -908,6 +913,9 @@ export class Unit {
908
913
 
909
914
 
910
915
  /**
916
+ * This function is not actually used by the other code, except for some test
917
+ * code, and might not be adequately tested.
918
+ *
911
919
  * Invert this unit with respect to multiplication. If this unit is not
912
920
  * on a ratio scale an exception is thrown. Mutating to a ratio scale unit
913
921
  * is not possible for a unit, only for a measurement (the magnitude and
@@ -918,14 +926,19 @@ export class Unit {
918
926
  * @throws and error if this unit is not on a ratio scale
919
927
  */
920
928
  invert() {
921
-
929
+ var retUnit = this.clone() ;
922
930
  if (this.cnv_ != null)
923
931
  throw (new Error(`Attempt to invert a non-ratio unit - ${this.name_}`));
924
932
 
925
- this.name_ = this.invertString(this.name_);
926
- this.magnitude_ = 1/this.magnitude_ ;
927
- this.dim_.minus();
928
- return this;
933
+ retUnit.name_ = this.invertString(this.name_);
934
+ retUnit.magnitude_ = 1/this.magnitude_ ;
935
+ retUnit.dim_.minus();
936
+
937
+ // Also update equivalentExp_ and moleExp
938
+ retUnit.equivalentExp_ = -this.equivalentExp_;
939
+ retUnit.moleExp_ = -this.moleExp_;
940
+
941
+ return retUnit;
929
942
 
930
943
  } // end invert
931
944
 
@@ -1010,6 +1023,9 @@ export class Unit {
1010
1023
 
1011
1024
 
1012
1025
  /**
1026
+ * This function is not actually used by the other code, except for some test
1027
+ * code, and might not be adequately tested.
1028
+ *
1013
1029
  * Raises the unit to a power. For example
1014
1030
  * kg.m/s2 raised to the -2 power would be kg-2.m-2/s-4
1015
1031
  *
@@ -1032,6 +1048,7 @@ export class Unit {
1032
1048
  throw (new Error(`Attempt to raise a non-ratio unit, ${this.name_}, ` +
1033
1049
  'to a power.'));
1034
1050
 
1051
+ var retUnit = this.clone() ;
1035
1052
  //this.name_ = UnitString.pow(this.name_, p);
1036
1053
  // the above line is replaced with the code below, as the pow method
1037
1054
  // never actually existing in the UnitString class. (Tried to use
@@ -1072,13 +1089,18 @@ export class Unit {
1072
1089
  } // end do for each element of the units array
1073
1090
 
1074
1091
  // reassemble the updated units array to a string
1075
- this.csCode_ = uArray.join('');
1092
+ retUnit.csCode_ = uArray.join('');
1076
1093
 
1077
- this.magnitude_ = Math.pow(this.magnitude_, p);
1078
- if (this.dim_) {
1079
- this.dim_.mul(p);
1094
+ retUnit.magnitude_ = Math.pow(this.magnitude_, p);
1095
+ if (retUnit.dim_) {
1096
+ retUnit.dim_.mul(p);
1080
1097
  }
1081
- return this;
1098
+
1099
+ // Also update equivalentExp_ and moleExp
1100
+ retUnit.equivalentExp_ *= p;
1101
+ retUnit.moleExp_ *= p;
1102
+
1103
+ return retUnit;
1082
1104
 
1083
1105
  } // end power
1084
1106
 
@@ -1099,25 +1121,19 @@ export class Unit {
1099
1121
  * @param unit2 the unit to be compared to this one
1100
1122
  * @returns boolean indicating commensurability
1101
1123
  */
1102
- isMoleMassCommensurable(unit2) {
1124
+ isMolMassCommensurable(unit2) {
1103
1125
  let tabs = this._getUnitTables();
1104
1126
  let d = tabs.getMassDimensionIndex();
1105
- let commensurable = false ;
1106
- if (this.moleExp_ === 1 && unit2.moleExp_ === 0) {
1107
- let testDim = this.dim_.clone();
1108
- let curVal = testDim.getElementAt(d);
1109
- testDim.setElementAt(d, (curVal + this.moleExp_));
1110
- commensurable = (testDim.equals(unit2.dim_));
1111
- }
1112
- else if (unit2.moleExp_ === 1 && this.moleExp_ === 0) {
1113
- let testDim = unit2.dim_.clone();
1114
- let curVal = testDim.getElementAt(d);
1115
- testDim.setElementAt(d, (curVal + unit2.moleExp_));
1116
- commensurable = (testDim.equals(this.dim_));
1117
- }
1118
- return commensurable ;
1127
+ // Add the moleExp_ values to the mass values in the dimension vectors
1128
+ // of each unit, and then compare them.
1129
+ const unit1Dim = this.dim_.clone();
1130
+ unit1Dim.setElementAt(d, (unit1Dim.getElementAt(d) + this.moleExp_));
1131
+ const unit2Dim = unit2.dim_.clone();
1132
+ unit2Dim.setElementAt(d, (unit2Dim.getElementAt(d) + unit2.moleExp_));
1133
+ return (unit1Dim.equals(unit2Dim));
1119
1134
  }
1120
1135
 
1136
+
1121
1137
  /**
1122
1138
  * This function tests this unit against the unit passed in to see if the
1123
1139
  * two are eq to mass commensurable. It assumes that one of the units
@@ -1137,20 +1153,57 @@ export class Unit {
1137
1153
  isEqMassCommensurable(unit2) {
1138
1154
  let tabs = this._getUnitTables();
1139
1155
  let d = tabs.getMassDimensionIndex();
1140
- let commensurable = false ;
1141
- if (this.equivalentExp_ === 1 && unit2.equivalentExp_ === 0) {
1142
- let testDim = this.dim_.clone();
1143
- let curVal = testDim.getElementAt(d);
1144
- testDim.setElementAt(d, (curVal + this.equivalentExp_));
1145
- commensurable = (testDim.equals(unit2.dim_));
1146
- }
1147
- else if (unit2.equivalentExp_ === 1 && this.equivalentExp_ === 0) {
1148
- let testDim = unit2.dim_.clone();
1149
- let curVal = testDim.getElementAt(d);
1150
- testDim.setElementAt(d, (curVal + unit2.equivalentExp_));
1151
- commensurable = (testDim.equals(this.dim_));
1152
- }
1153
- return commensurable;
1156
+ // Add the equivalentExp_ values to the mass values in the dimension vectors
1157
+ // of each unit, and then compare them.
1158
+ const unit1Dim = this.dim_.clone();
1159
+ unit1Dim.setElementAt(d, (unit1Dim.getElementAt(d) + this.equivalentExp_));
1160
+ const unit2Dim = unit2.dim_.clone();
1161
+ unit2Dim.setElementAt(d, (unit2Dim.getElementAt(d) + unit2.equivalentExp_));
1162
+ return (unit1Dim.equals(unit2Dim));
1163
+ }
1164
+
1165
+ /**
1166
+ * This function tests this unit against the unit passed in to see if the
1167
+ * two are eq to mass commensurable-- that the equivalents could be converted
1168
+ * to the mass or vice-versa, in a way that makes the units commensurable.
1169
+ *
1170
+ * The check is made by adding the mole dimension to the equivalent dimension
1171
+ * and comparing that result for the two units, along with the units'
1172
+ * dimension vectors. If they match, the units are
1173
+ * commensurable. Otherwise they are not.
1174
+ *
1175
+ * @param {Unit} unit2 the unit to be compared to this one
1176
+ * @returns {boolean} boolean indicating commensurability
1177
+ */
1178
+ isEqMolCommensurable(unit2) {
1179
+ const unit1Sum = this.equivalentExp_ + this.moleExp_;
1180
+ const unit2Sum = unit2.equivalentExp_ + unit2.moleExp_;
1181
+ return unit1Sum == unit2Sum && this.dim_.equals(unit2.dim_);
1182
+ }
1183
+
1184
+
1185
+ /**
1186
+ * This function tests this unit against the unit passed in to see if the
1187
+ * two are commensurable if eq, mol, and mass units are converted in some
1188
+ * direction.
1189
+ *
1190
+ * The check is made by adding the eq, mol, and mass dimensions
1191
+ * and comparing that result for the two units, along with the units'
1192
+ * dimension vectors. If they match, the units are
1193
+ * commensurable. Otherwise they are not.
1194
+ *
1195
+ * @param {Unit} unit2 the unit to be compared to this one
1196
+ * @returns {boolean} boolean indicating commensurability
1197
+ */
1198
+ isEqMolMassCommensurable(unit2) {
1199
+ const d = this._getUnitTables().getMassDimensionIndex();
1200
+ const unit1Dim = this.dim_.clone();
1201
+ unit1Dim.setElementAt(d, unit1Dim.getElementAt(d) + this.equivalentExp_ +
1202
+ this.moleExp_);
1203
+ const unit2Dim = unit2.dim_.clone();
1204
+ unit2Dim.setElementAt(d, unit2Dim.getElementAt(d) + unit2.equivalentExp_ +
1205
+ unit2.moleExp_);
1206
+ return unit1Dim.equals(unit2Dim);
1154
1207
  }
1155
1208
 
1156
1209
 
@@ -1250,6 +1250,8 @@ export class UnitString {
1250
1250
  let expMul = exp;
1251
1251
  if (theDim)
1252
1252
  theDim = theDim.mul(exp);
1253
+ retUnit.equivalentExp_ *= exp;
1254
+ retUnit.moleExp_ *= exp;
1253
1255
  theMag = Math.pow(theMag, exp);
1254
1256
  retUnit.assignVals({'magnitude_': theMag});
1255
1257