/* * Copyright (c) 1995, 1996 Gunther Schadow. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "pg_config.h" IDENT("@(#) Unit.cc (Gunther Schadow) 12/19/96"); #pragma implementation "Unit.h" #include "Unit.h" #include #include #include #include #include #include // for sprintf only! Unit::Unit() : Code() { unit = UnitAtom::null_unit; } Unit::Unit(const Unit& x) : Code() { unit = x.unit; unit.name = strdup(unit.name); } Unit::Unit(const char *name) : Code() { set(name); } Unit::~Unit() { if(unit.name != UnitAtom::null_unit.name) delete [] unit.name; } Unit& Unit::operator = (const Unit& x) { if(unit.name != UnitAtom::null_unit.name) delete [] unit.name; unit = x.unit; unit.name = strdup(unit.name); return *this; } Unit Unit::operator * (const Unit& x) const return r { r.unit.name = new char[strlen(unit.name) + strlen(x.unit.name) + 2]; strcpy(r.unit.name, unit.name); strcat(r.unit.name, "."); strcat(r.unit.name, x.unit.name); r.unit.coeff_mantissa = unit.coeff_mantissa * x.unit.coeff_mantissa; r.unit.coeff_exponent = unit.coeff_exponent + x.unit.coeff_exponent; r.unit.base = unit.base + x.unit.base; } Unit Unit::operator / (const Unit &x) const return r { r.unit.name = new char[strlen(unit.name) + strlen(x.unit.name) + 2]; strcpy(r.unit.name, unit.name); strcat(r.unit.name, "/"); char *xun = invert(x.unit.name); if(*xun == '/') strcat(r.unit.name, &xun[1]); else strcat(r.unit.name, xun); delete [] xun; r.unit.coeff_mantissa = unit.coeff_mantissa / x.unit.coeff_mantissa; r.unit.coeff_exponent = unit.coeff_exponent - x.unit.coeff_exponent; r.unit.base = unit.base - x.unit.base; } Unit& Unit::pow(int i) { char *old_name = unit.name; unit.name = pow(unit.name, i); if(old_name != UnitAtom::null_unit.name) delete [] old_name; unit.coeff_mantissa = ::pow(unit.coeff_mantissa, i); unit.coeff_exponent = unit.coeff_exponent * i; unit.base = unit.base * i; return *this; } Unit& Unit::invert() { char *old_name = unit.name; unit.name = invert(unit.name); if(old_name != UnitAtom::null_unit.name) delete [] old_name; unit.coeff_mantissa = 1 / unit.coeff_mantissa; unit.coeff_exponent = - unit.coeff_exponent; unit.base = - unit.base; return *this; } Unit& Unit::operator *= (const Unit &x) { char *old_name = unit.name; unit.name = new char[strlen(old_name) + strlen(x.unit.name) + 2]; strcpy(unit.name, old_name); strcat(unit.name, "."); strcat(unit.name, x.unit.name); if(old_name != UnitAtom::null_unit.name) delete [] old_name; unit.coeff_mantissa = unit.coeff_mantissa * x.unit.coeff_mantissa; unit.coeff_exponent = unit.coeff_exponent + x.unit.coeff_exponent; unit.base = unit.base + x.unit.base; return *this; } Unit& Unit::operator /= (const Unit &x) { char *old_name = unit.name; unit.name = new char[strlen(old_name) + strlen(x.unit.name) + 2]; strcpy(unit.name, old_name); strcat(unit.name, "/"); char *xun = invert(x.unit.name); if(*xun == '/') strcat(unit.name, &xun[1]); else strcat(unit.name, xun); delete [] xun; if(old_name != UnitAtom::null_unit.name) delete [] old_name; unit.coeff_mantissa = unit.coeff_mantissa / x.unit.coeff_mantissa; unit.coeff_exponent = unit.coeff_exponent - x.unit.coeff_exponent; unit.base = unit.base - x.unit.base; return *this; } bool Unit::operator == (const Unit &x) const { return unit.base == x.unit.base && unit.coeff_mantissa == x.unit.coeff_mantissa && unit.coeff_exponent == x.unit.coeff_exponent; } double convert(double v1, const Unit &u1, const Unit &u2) { double v2, x; if(u1->base == u2->base) { if(u1->cnv_from == NULL && u2-> cnv_to == NULL) v2 = v1 * (u1->coeff_mantissa / u2->coeff_mantissa) * pow(10, (double)(u1->coeff_exponent - u2->coeff_exponent)); else { if(u1->cnv_from != NULL) x = (*u1->cnv_from)(v1) * u1->coeff_mantissa * pow(10, u1->coeff_exponent); else x = v1 * u1->coeff_mantissa * pow(10, u1->coeff_exponent); if(u2->cnv_to != NULL) v2 = (*u2->cnv_to)(x / u2->coeff_mantissa / pow(10, u2->coeff_exponent)); else v2 = x / u2->coeff_mantissa / pow(10, u2->coeff_exponent); } return v2; } else ERROR("incommensurable units: %s, %s", (const char*)u1, (const char *)u2); }