Annotation of loncom/homework/math_parser/Quantity.pm, revision 1.1
1.1 ! damieng 1: # The LearningOnline Network with CAPA - LON-CAPA
! 2: # Quantity
! 3: #
! 4: # Copyright (C) 2014 Michigan State University Board of Trustees
! 5: #
! 6: # This program is free software: you can redistribute it and/or modify
! 7: # it under the terms of the GNU General Public License as published by
! 8: # the Free Software Foundation, either version 3 of the License, or
! 9: # (at your option) any later version.
! 10: #
! 11: # This program is distributed in the hope that it will be useful,
! 12: # but WITHOUT ANY WARRANTY; without even the implied warranty of
! 13: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 14: # GNU General Public License for more details.
! 15: #
! 16: # You should have received a copy of the GNU General Public License
! 17: # along with this program. If not, see <http://www.gnu.org/licenses/>.
! 18: #
! 19:
! 20: ##
! 21: # A quantity (value and units)
! 22: ##
! 23: package Apache::math_parser::Quantity;
! 24:
! 25: use strict;
! 26: use warnings;
! 27: use utf8;
! 28:
! 29: use POSIX;
! 30: use Math::Complex; # must be after POSIX for redefinition of log10
! 31:
! 32: use aliased 'Apache::math_parser::CalcException';
! 33: use aliased 'Apache::math_parser::Quantity';
! 34: use aliased 'Apache::math_parser::QVector';
! 35: use aliased 'Apache::math_parser::QMatrix';
! 36: use aliased 'Apache::math_parser::QSet';
! 37: use aliased 'Apache::math_parser::QInterval';
! 38: use aliased 'Apache::math_parser::QIntervalUnion';
! 39:
! 40: use overload
! 41: '""' => \&toString,
! 42: '+' => \&qadd,
! 43: '-' => \&qsub,
! 44: '*' => \&qmult,
! 45: '/' => \&qdiv,
! 46: '^' => \&qpow,
! 47: '<' => \&qlt,
! 48: '<=' => \&qle,
! 49: '>' => \&qgt,
! 50: '>=' => \&qge,
! 51: '<=>' => \&perl_compare;
! 52:
! 53: # compare() return codes:
! 54: use enum qw(IDENTICAL WRONG_TYPE WRONG_DIMENSIONS MISSING_UNITS ADDED_UNITS WRONG_UNITS WRONG_VALUE WRONG_ENDPOINT);
! 55:
! 56:
! 57: ##
! 58: # Constructor
! 59: # @param {complex} value
! 60: # @optional {Object.<string, integer>} units - hash: unit name -> exponent for each SI unit
! 61: ##
! 62: sub new {
! 63: my $class = shift;
! 64: my $self = {
! 65: _value => shift,
! 66: _units => shift,
! 67: };
! 68: if ("".$self->{_value} eq "i") {
! 69: $self->{_value} = i;
! 70: } elsif ("".$self->{_value} eq "inf") {
! 71: $self->{_value} = 9**9**9;
! 72: }
! 73: if (!defined $self->{_units}) {
! 74: $self->{_units} = {
! 75: s => 0,
! 76: m => 0,
! 77: kg => 0,
! 78: K => 0,
! 79: A => 0,
! 80: mol => 0,
! 81: cd => 0
! 82: };
! 83: } else {
! 84: foreach my $unit ('s', 'm', 'kg', 'K', 'A', 'mol', 'cd') {
! 85: if (!defined $self->{_units}->{$unit}) {
! 86: $self->{_units}->{$unit} = 0;
! 87: }
! 88: }
! 89: }
! 90: bless $self, $class;
! 91: return $self;
! 92: }
! 93:
! 94: # Attribute helpers
! 95:
! 96: ##
! 97: # Value.
! 98: # @returns {Complex}
! 99: ##
! 100: sub value {
! 101: my $self = shift;
! 102: return $self->{_value};
! 103: }
! 104:
! 105:
! 106: ##
! 107: # Units
! 108: # @returns {Object.<string, integer>} hash: unit name -> exponent for each SI unit
! 109: ##
! 110: sub units {
! 111: my $self = shift;
! 112: return $self->{_units};
! 113: }
! 114:
! 115:
! 116: ##
! 117: # Returns a readable view of the object
! 118: # @returns {string}
! 119: ##
! 120: sub toString {
! 121: my ( $self ) = @_;
! 122: my $s;
! 123: # complex display in polar notation can be confused with vectors
! 124: # normally we should just have to call Math::Complex::display_format('cartesian');
! 125: # actually, it's supposed to be the default...
! 126: # but this is not working, so...
! 127: if ($self->value =~ /\[/) {
! 128: my $v = $self->value;
! 129: $v->display_format('cartesian');
! 130: $s = "".$v;
! 131: } else {
! 132: $s = $self->value;
! 133: }
! 134: foreach my $unit (keys %{$self->units}) {
! 135: my $e = $self->units->{$unit};
! 136: if ($e != 0) {
! 137: $s .= " ".$unit;
! 138: if ($e != 1) {
! 139: $s .= "^".$e;
! 140: }
! 141: }
! 142: }
! 143: return $s;
! 144: }
! 145:
! 146: ##
! 147: # Equality test
! 148: # @param {Quantity}
! 149: # @optional {string|float} tolerance
! 150: # @returns {boolean}
! 151: ##
! 152: sub equals {
! 153: my ( $self, $q, $tolerance ) = @_;
! 154: if (!$q->isa(Quantity)) {
! 155: return 0;
! 156: }
! 157: if (!defined $tolerance) {
! 158: $tolerance = 0;
! 159: }
! 160: if ($tolerance =~ /%/) {
! 161: my $perc = $tolerance;
! 162: $perc =~ s/%//;
! 163: $perc /= 100;
! 164: if (abs($self->value - $q->value) > abs($self->value * $perc)) {
! 165: return 0;
! 166: }
! 167: } else {
! 168: if (abs($self->value - $q->value) > $tolerance) {
! 169: return 0;
! 170: }
! 171: }
! 172: my %units = %{$self->units};
! 173: foreach my $unit (keys %units) {
! 174: if ($units{$unit} != $q->units->{$unit}) {
! 175: return 0;
! 176: }
! 177: }
! 178: return 1;
! 179: }
! 180:
! 181: ##
! 182: # Compare this quantity with another one, and returns a code.
! 183: # Returns Quantity->WRONG_TYPE if the parameter is not a Quantity.
! 184: # @param {Quantity|QVector|QMatrix|QSet|QInterval} q
! 185: # @optional {string|float} tolerance
! 186: # @returns {int} WRONG_TYPE|MISSING_UNITS|ADDED_UNITS|WRONG_UNITS|WRONG_VALUE|IDENTICAL
! 187: ##
! 188: sub compare {
! 189: my ( $self, $q, $tolerance ) = @_;
! 190: if (!$q->isa(Quantity)) {
! 191: return WRONG_TYPE;
! 192: }
! 193: if (!defined $tolerance) {
! 194: $tolerance = 0;
! 195: }
! 196: my %units = %{$self->units};
! 197: my $this_has_units = 0;
! 198: my $other_has_units = 0;
! 199: my $wrong_units = 0;
! 200: foreach my $unit (keys %units) {
! 201: if ($units{$unit} != 0) {
! 202: $this_has_units = 1;
! 203: }
! 204: if ($q->units->{$unit} != 0) {
! 205: $other_has_units = 1;
! 206: }
! 207: if ($units{$unit} != $q->units->{$unit}) {
! 208: $wrong_units = 1;
! 209: }
! 210: }
! 211: if ($this_has_units && !$other_has_units) {
! 212: return MISSING_UNITS;
! 213: } elsif (!$this_has_units && $other_has_units) {
! 214: return ADDED_UNITS;
! 215: }
! 216: if ($wrong_units) {
! 217: return WRONG_UNITS;
! 218: }
! 219: if ($tolerance =~ /%/) {
! 220: my $perc = $tolerance;
! 221: $perc =~ s/%//;
! 222: $perc /= 100;
! 223: if (abs($self->value - $q->value) > abs($self->value * $perc)) {
! 224: return WRONG_VALUE;
! 225: }
! 226: } else {
! 227: if (abs($self->value - $q->value) > $tolerance) {
! 228: return WRONG_VALUE;
! 229: }
! 230: }
! 231: return IDENTICAL;
! 232: }
! 233:
! 234: ##
! 235: # <=> operator.
! 236: # Compare this quantity with another one, and returns -1, 0 or 1.
! 237: # @param {Quantity} q
! 238: # @returns {int}
! 239: ##
! 240: sub perl_compare {
! 241: my ( $self, $q ) = @_;
! 242: if (!$q->isa(Quantity)) {
! 243: die CalcException->new("Quantity comparison: second member is not a quantity.");
! 244: }
! 245: $self->unitsMatch($q, 'perl_compare');
! 246: return($self->value <=> $q->value);
! 247: }
! 248:
! 249: ##
! 250: # Not equal
! 251: # @param {Quantity} q
! 252: # @optional {string|float} tolerance
! 253: # @returns {boolean}
! 254: ##
! 255: sub ne {
! 256: my ( $self, $q, $tolerance ) = @_;
! 257: if ($self->equals($q, $tolerance)) {
! 258: return(0);
! 259: } else {
! 260: return(1);
! 261: }
! 262: }
! 263:
! 264: ##
! 265: # Less than
! 266: # @param {Quantity} q
! 267: # @returns {boolean}
! 268: ##
! 269: sub lt {
! 270: my ( $self, $q ) = @_;
! 271: if (!$q->isa(Quantity)) {
! 272: die CalcException->new("Quantity smaller than: second member is not a quantity.");
! 273: }
! 274: $self->unitsMatch($q, 'lt');
! 275: if ($self->value < $q->value) {
! 276: return(1);
! 277: } else {
! 278: return(0);
! 279: }
! 280: }
! 281:
! 282: ##
! 283: # Less than or equal
! 284: # @param {Quantity} q
! 285: # @returns {boolean}
! 286: ##
! 287: sub le {
! 288: my ( $self, $q ) = @_;
! 289: if (!$q->isa(Quantity)) {
! 290: die CalcException->new("Quantity smaller or equal: second member is not a quantity.");
! 291: }
! 292: $self->unitsMatch($q, 'le');
! 293: if ($self->value <= $q->value) {
! 294: return(1);
! 295: } else {
! 296: return(0);
! 297: }
! 298: }
! 299:
! 300: ##
! 301: # Greater than
! 302: # @param {Quantity} q
! 303: # @returns {boolean}
! 304: ##
! 305: sub gt {
! 306: my ( $self, $q ) = @_;
! 307: if (!$q->isa(Quantity)) {
! 308: die CalcException->new("Quantity greater than: second member is not a quantity.");
! 309: }
! 310: $self->unitsMatch($q, 'gt');
! 311: if ($self->value > $q->value) {
! 312: return(1);
! 313: } else {
! 314: return(0);
! 315: }
! 316: }
! 317:
! 318: ##
! 319: # Greater than or equal
! 320: # @param {Quantity} q
! 321: # @returns {boolean}
! 322: ##
! 323: sub ge {
! 324: my ( $self, $q ) = @_;
! 325: if (!$q->isa(Quantity)) {
! 326: die CalcException->new("Quantity greater or equal: second member is not a quantity.");
! 327: }
! 328: $self->unitsMatch($q, 'ge');
! 329: if ($self->value >= $q->value) {
! 330: return(1);
! 331: } else {
! 332: return(0);
! 333: }
! 334: }
! 335:
! 336: ##
! 337: # Clone this object
! 338: # @returns {Quantity}
! 339: ##
! 340: sub clone {
! 341: my ( $self ) = @_;
! 342: my %units = %{$self->units};
! 343: return Quantity->new($self->value, \%units);
! 344: }
! 345:
! 346: ##
! 347: # Addition
! 348: # @param {Quantity} q
! 349: # @returns {Quantity}
! 350: ##
! 351: sub qadd {
! 352: my ( $self, $q ) = @_;
! 353: if (!$q->isa(Quantity)) {
! 354: die CalcException->new("Quantity addition: second member is not a quantity.");
! 355: }
! 356: my $v = $self->value + $q->value;
! 357: $self->unitsMatch($q, 'addition');
! 358: return Quantity->new($v, $self->units);
! 359: }
! 360:
! 361: ##
! 362: # Substraction
! 363: # @param {Quantity} q
! 364: # @returns {Quantity}
! 365: ##
! 366: sub qsub {
! 367: my ( $self, $q ) = @_;
! 368: if (!$q->isa(Quantity)) {
! 369: die CalcException->new("Quantity substraction: second member is not a quantity.");
! 370: }
! 371: my $v = $self->value - $q->value;
! 372: $self->unitsMatch($q, 'substraction');
! 373: return Quantity->new($v, $self->units);
! 374: }
! 375:
! 376: ##
! 377: # Negation
! 378: # @returns {Quantity}
! 379: ##
! 380: sub qneg {
! 381: my ( $self ) = @_;
! 382: my $v = - $self->value;
! 383: my %units = %{$self->units};
! 384: return Quantity->new($v, \%units);
! 385: }
! 386:
! 387: ##
! 388: # Multiplication
! 389: # @param {Quantity|QVector|QMatrix|QSet|QInterval|QIntervalUnion} qv
! 390: # @returns {Quantity|QVector|QMatrix|QSet|QInterval|QIntervalUnion}
! 391: ##
! 392: sub qmult {
! 393: my ( $self, $qv ) = @_;
! 394: if (!$qv->isa(Quantity) && !$qv->isa(QVector) && !$qv->isa(QMatrix) &&
! 395: !$qv->isa(QSet) && !$qv->isa(QInterval) && !$qv->isa(QIntervalUnion)) {
! 396: die CalcException->new("Cannot multiply with something that is not a quantity, vector, matrix, set, or interval.");
! 397: }
! 398: if ($qv->isa(QVector) || $qv->isa(QMatrix) || $qv->isa(QSet) || $qv->isa(QInterval) || $qv->isa(QIntervalUnion)) {
! 399: return($qv->qmult($self));
! 400: }
! 401: my $q = $qv;
! 402: my $v = $self->value * $q->value;
! 403: my %units = %{$self->units};
! 404: foreach my $unit (keys %units) {
! 405: $units{$unit} = $units{$unit} + $q->units->{$unit};
! 406: }
! 407: return Quantity->new($v, \%units);
! 408: }
! 409:
! 410: ##
! 411: # Division
! 412: # @param {Quantity} q
! 413: # @returns {Quantity}
! 414: ##
! 415: sub qdiv {
! 416: my ( $self, $q ) = @_;
! 417: if (!$q->isa(Quantity)) {
! 418: die CalcException->new("Cannot divide by something that is not a quantity.");
! 419: }
! 420: if ($q->value == 0) {
! 421: die CalcException->new("Division by zero.");
! 422: }
! 423: my $v = $self->value / $q->value;
! 424: my %units = %{$self->units};
! 425: foreach my $unit (keys %units) {
! 426: $units{$unit} = $units{$unit} - $q->units->{$unit};
! 427: }
! 428: return Quantity->new($v, \%units);
! 429: }
! 430:
! 431: ##
! 432: # Power
! 433: # @param {Quantity} q
! 434: # @returns {Quantity}
! 435: ##
! 436: sub qpow {
! 437: my ( $self, $q ) = @_;
! 438: if (!$q->isa(Quantity)) {
! 439: die CalcException->new("Cannot raise to the power of something that is not a number.");
! 440: }
! 441: my $v = $self->value ** $q->value;
! 442: $q->noUnits("Power");
! 443: my %units = %{$self->units};
! 444: foreach my $unit (keys %{$q->units}) {
! 445: $units{$unit} = $units{$unit} * $q->value;
! 446: }
! 447: return Quantity->new($v, \%units);
! 448: }
! 449:
! 450: ##
! 451: # Factorial
! 452: # @returns {Quantity}
! 453: ##
! 454: sub qfact {
! 455: my ( $self ) = @_;
! 456: my $v = $self->value;
! 457: if ($v < 0) {
! 458: die CalcException->new("Factorial of a number smaller than zero.");
! 459: }
! 460: # should check if integer
! 461: my $n = $v;
! 462: for (my $i=$n - 1; $i > 1; $i--) {
! 463: $v *= $i;
! 464: }
! 465: return Quantity->new($v, $self->units);
! 466: }
! 467:
! 468: ##
! 469: # Square root
! 470: # @returns {Quantity}
! 471: ##
! 472: sub qsqrt {
! 473: my ( $self ) = @_;
! 474: my $v = sqrt($self->value);
! 475: my %units = %{$self->units};
! 476: foreach my $unit (keys %units) {
! 477: $units{$unit} = $units{$unit} / 2;
! 478: }
! 479: return Quantity->new($v, \%units);
! 480: }
! 481:
! 482: ##
! 483: # Absolute value
! 484: # @returns {Quantity}
! 485: ##
! 486: sub qabs {
! 487: my ( $self ) = @_;
! 488: my $v = abs($self->value);
! 489: my %units = %{$self->units};
! 490: return Quantity->new($v, \%units);
! 491: }
! 492:
! 493: ##
! 494: # Exponential
! 495: # @returns {Quantity}
! 496: ##
! 497: sub qexp {
! 498: my ( $self ) = @_;
! 499: $self->noUnits("exp");
! 500: return Quantity->new(exp($self->value), $self->units);
! 501: }
! 502:
! 503: ##
! 504: # Natural logarithm
! 505: # @returns {Quantity}
! 506: ##
! 507: sub qln {
! 508: my ( $self ) = @_;
! 509: $self->noUnits("ln");
! 510: # this will return a complex if the value is < 0
! 511: #if ($self->value < 0) {
! 512: # die CalcException->new("Ln of number < 0");
! 513: #}
! 514: if ($self->value == 0) {
! 515: die CalcException->new("Natural logarithm of zero.");
! 516: }
! 517: return Quantity->new(log($self->value), $self->units);
! 518: }
! 519:
! 520: ##
! 521: # Decimal logarithm
! 522: # @returns {Quantity}
! 523: ##
! 524: sub qlog10 {
! 525: my ( $self ) = @_;
! 526: $self->noUnits("log10");
! 527: # this will return a complex if the value is < 0
! 528: #if ($self->value < 0) {
! 529: # die CalcException->new("Log10 of number < 0");
! 530: #}
! 531: if ($self->value == 0) {
! 532: die CalcException->new("Logarithm of zero.");
! 533: }
! 534: return Quantity->new(log10($self->value), $self->units);
! 535: }
! 536:
! 537: ##
! 538: # Modulo
! 539: # @param {Quantity} q
! 540: # @returns {Quantity}
! 541: ##
! 542: sub qmod {
! 543: my ( $self, $q ) = @_;
! 544: if (!$q->isa(Quantity)) {
! 545: die CalcException->new("Cannot calculate the modulus with respect to something that is not a quantity.");
! 546: }
! 547: my $v = $self->value % $q->value;
! 548: return Quantity->new($v, $self->units);
! 549: }
! 550:
! 551: ##
! 552: # Returns -1, 0 or 1 depending on the sign of the value
! 553: # @returns {Quantity}
! 554: ##
! 555: sub qsgn {
! 556: my ( $self ) = @_;
! 557: my $v;
! 558: if ($self->value < 0) {
! 559: $v = -1;
! 560: } elsif ($self->value > 0) {
! 561: $v = 1;
! 562: } else {
! 563: $v = 0;
! 564: }
! 565: return Quantity->new($v, $self->units);
! 566: }
! 567:
! 568: ##
! 569: # Returns the least integer that is greater than or equal to the value.
! 570: # @returns {Quantity}
! 571: ##
! 572: sub qceil {
! 573: my ( $self ) = @_;
! 574: my $v = ceil($self->value);
! 575: return Quantity->new($v, $self->units);
! 576: }
! 577:
! 578: ##
! 579: # Returns the largest integer that is less than or equal to the value.
! 580: # @returns {Quantity}
! 581: ##
! 582: sub qfloor {
! 583: my ( $self ) = @_;
! 584: my $v = floor($self->value);
! 585: return Quantity->new($v, $self->units);
! 586: }
! 587:
! 588: ##
! 589: # Sine
! 590: # @returns {Quantity}
! 591: ##
! 592: sub qsin {
! 593: my ( $self ) = @_;
! 594: $self->noUnits("sin");
! 595: return Quantity->new(sin($self->value), $self->units);
! 596: }
! 597:
! 598: ##
! 599: # Cosine
! 600: # @returns {Quantity}
! 601: ##
! 602: sub qcos {
! 603: my ( $self ) = @_;
! 604: $self->noUnits("cos");
! 605: return Quantity->new(cos($self->value), $self->units);
! 606: }
! 607:
! 608: ##
! 609: # Tangent
! 610: # @returns {Quantity}
! 611: ##
! 612: sub qtan {
! 613: my ( $self ) = @_;
! 614: $self->noUnits("tan");
! 615: return Quantity->new(tan($self->value), $self->units);
! 616: }
! 617:
! 618: ##
! 619: # Arcsinus
! 620: # @returns {Quantity}
! 621: ##
! 622: sub qasin {
! 623: my ( $self ) = @_;
! 624: $self->noUnits("asin");
! 625: return Quantity->new(asin($self->value), $self->units);
! 626: }
! 627:
! 628: ##
! 629: # Arccosinus
! 630: # @returns {Quantity}
! 631: ##
! 632: sub qacos {
! 633: my ( $self ) = @_;
! 634: $self->noUnits("acos");
! 635: return Quantity->new(acos($self->value), $self->units);
! 636: }
! 637:
! 638: ##
! 639: # Arctangent
! 640: # @returns {Quantity}
! 641: ##
! 642: sub qatan {
! 643: my ( $self ) = @_;
! 644: $self->noUnits("atan");
! 645: return Quantity->new(atan($self->value), $self->units);
! 646: }
! 647:
! 648: ##
! 649: # Arctangent of self/x in the range -pi to pi
! 650: # @param {Quantity} x
! 651: # @returns {Quantity}
! 652: ##
! 653: sub qatan2 {
! 654: my ( $self, $q ) = @_;
! 655: if (!$q->isa(Quantity)) {
! 656: die CalcException->new("Cannot calculate atan2 if second argument is not a quantity.");
! 657: }
! 658: $self->noUnits("atan2");
! 659: my $v = atan2($self->value, $q->value);
! 660: return Quantity->new($v, $self->units);
! 661: }
! 662:
! 663: ##
! 664: # Hyperbolic sinus
! 665: # @returns {Quantity}
! 666: ##
! 667: sub qsinh {
! 668: my ( $self ) = @_;
! 669: $self->noUnits("sinh");
! 670: return Quantity->new(sinh($self->value), $self->units);
! 671: }
! 672:
! 673: ##
! 674: # Hyperbolic cosinus
! 675: # @returns {Quantity}
! 676: ##
! 677: sub qcosh {
! 678: my ( $self ) = @_;
! 679: $self->noUnits("cosh");
! 680: return Quantity->new(cosh($self->value), $self->units);
! 681: }
! 682:
! 683: ##
! 684: # Hyperbolic tangent
! 685: # @returns {Quantity}
! 686: ##
! 687: sub qtanh {
! 688: my ( $self ) = @_;
! 689: $self->noUnits("tanh");
! 690: return Quantity->new(tanh($self->value), $self->units);
! 691: }
! 692:
! 693: ##
! 694: # Hyperbolic arcsinus
! 695: # @returns {Quantity}
! 696: ##
! 697: sub qasinh {
! 698: my ( $self ) = @_;
! 699: $self->noUnits("asinh");
! 700: return Quantity->new(asinh($self->value), $self->units);
! 701: }
! 702:
! 703: ##
! 704: # Hyperbolic arccosinus
! 705: # @returns {Quantity}
! 706: ##
! 707: sub qacosh {
! 708: my ( $self ) = @_;
! 709: $self->noUnits("acosh");
! 710: return Quantity->new(acosh($self->value), $self->units);
! 711: }
! 712:
! 713: ##
! 714: # Hyperbolic arctangent
! 715: # @returns {Quantity}
! 716: ##
! 717: sub qatanh {
! 718: my ( $self ) = @_;
! 719: $self->noUnits("atanh");
! 720: return Quantity->new(atanh($self->value), $self->units);
! 721: }
! 722:
! 723: ##
! 724: # Equals
! 725: # @param {Quantity|QVector|QMatrix|QSet|QInterval} q
! 726: # @optional {string|float} tolerance
! 727: # @returns {Quantity}
! 728: ##
! 729: sub qeq {
! 730: my ( $self, $q, $tolerance ) = @_;
! 731: my $v = $self->equals($q, $tolerance);
! 732: return Quantity->new($v);
! 733: }
! 734:
! 735: ##
! 736: # Less than
! 737: # @param {Quantity}
! 738: # @returns {Quantity}
! 739: ##
! 740: sub qlt {
! 741: my ( $self, $q ) = @_;
! 742: my $v = $self->lt($q);
! 743: return Quantity->new($v);
! 744: }
! 745:
! 746: ##
! 747: # Less than or equal
! 748: # @param {Quantity} q
! 749: # @returns {Quantity}
! 750: ##
! 751: sub qle {
! 752: my ( $self, $q ) = @_;
! 753: my $v = $self->le($q);
! 754: return Quantity->new($v);
! 755: }
! 756:
! 757: ##
! 758: # Greater than
! 759: # @param {Quantity} q
! 760: # @returns {Quantity}
! 761: ##
! 762: sub qgt {
! 763: my ( $self, $q ) = @_;
! 764: my $v = $self->gt($q);
! 765: return Quantity->new($v);
! 766: }
! 767:
! 768: ##
! 769: # Greater than or equal
! 770: # @param {Quantity} q
! 771: # @returns {Quantity}
! 772: ##
! 773: sub qge {
! 774: my ( $self, $q ) = @_;
! 775: my $v = $self->ge($q);
! 776: return Quantity->new($v);
! 777: }
! 778:
! 779: ##
! 780: # Dies if units do not match.
! 781: ##
! 782: sub unitsMatch {
! 783: my ( $self, $q, $fct_name ) = @_;
! 784: my %units = %{$self->units};
! 785: foreach my $unit (keys %units) {
! 786: if ($units{$unit} != $q->units->{$unit}) {
! 787: die CalcException->new("Units [_1] do not match.", $fct_name);
! 788: }
! 789: }
! 790: }
! 791:
! 792: ##
! 793: # Dies if there are any unit.
! 794: ##
! 795: sub noUnits {
! 796: my ( $self, $fct_name ) = @_;
! 797: my %units = %{$self->units};
! 798: foreach my $unit (keys %units) {
! 799: if ($units{$unit} != 0) {
! 800: die CalcException->new("Cannot calculate [_1] of something with units.", $fct_name);
! 801: }
! 802: }
! 803: }
! 804:
! 805: 1;
! 806: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>