Skip to main content

Derived units

Multiplication, division, and exponentiation combine quantities into derived quantity types. Each operation validates that the combination is supported and throws InvalidArgumentException otherwise.

Multiplication

multiply() returns the product as a derived quantity:

use Renfordt\UnitLib\{Length, Mass, Acceleration};

// Length × Length = Area
$area = (new Length(5, 'm'))->multiply(new Length(3, 'm'));
$area->toUnit('m²'); // 15

// Area × Length = Volume
$volume = $area->multiply(new Length(2, 'm'));
$volume->toUnit('m³'); // 30

// Mass × Acceleration = Force
$force = (new Mass(10, 'kg'))->multiply(new Acceleration(9.8, 'm/s²'));
$force->toUnit('N'); // 98

Supported multiplication combinations:

OperandsResult
Length × LengthArea
Area × LengthVolume
Mass × AccelerationForce
Force × LengthEnergy or Torque (see below)
Current × ResistanceVoltage
Voltage × TimeMagneticFlux
Current × TimeCharge

The order of the operands does not matter for the supported pairs.

Resolving Force × Length

Force × Length is dimensionally ambiguous: it can represent energy (work) or torque. By default the result is Energy. Pass the desired result class as the second argument to multiply() to get Torque instead:

use Renfordt\UnitLib\{Force, Length, Torque};

$force = new Force(10, 'N');

$work = $force->multiply(new Length(5, 'm'));
$work->toUnit('J'); // 50 (Energy, default)

$torque = $force->multiply(new Length(0.5, 'm'), Torque::class);
$torque->toUnit('N⋅m'); // 5 (Torque)

Division

divide() returns the quotient as a derived quantity. Dividing by a quantity whose native value is zero throws InvalidArgumentException:

use Renfordt\UnitLib\{Length, Time};

$velocity = (new Length(100, 'm'))->divide(new Time(10, 's'));
$velocity->toUnit('m/s'); // 10

$acceleration = $velocity->divide(new Time(10, 's'));
$acceleration->toUnit('m/s²'); // 1

Supported division combinations:

OperandsResult
Length / TimeVelocity
Length / VelocityTime
Velocity / TimeAcceleration
Energy / TimePower
Force / AreaPressure
Area / LengthLength
Volume / LengthArea
Volume / AreaLength
Voltage / CurrentResistance
Voltage / ResistanceCurrent
Charge / VoltageCapacitance
MagneticFlux / CurrentInductance

Exponentiation

power() raises a quantity to an integer exponent:

use Renfordt\UnitLib\Length;

$area = (new Length(5, 'm'))->power(2);
$area->toUnit('m²'); // 25

$volume = (new Length(3, 'm'))->power(3);
$volume->toUnit('m³'); // 27

Behavior by exponent:

  • power(1) returns a clone of the quantity, unchanged.
  • power(0) throws InvalidArgumentException.
  • Only Length² (Area) and Length³ (Volume) are supported. Time² is explicitly rejected with guidance to use division instead; any other unsupported combination throws InvalidArgumentException.

Factory methods

Some derived quantities provide static factory methods that wrap the corresponding operation for readability.

use Renfordt\UnitLib\{Velocity, Acceleration, Length, Time};

// Velocity from Length and Time (equivalent to $length->divide($time))
$v = Velocity::fromLengthAndTime(new Length(100, 'm'), new Time(10, 's'));
$v->toUnit('km/h'); // 36

// Acceleration from Velocity and Time
$a1 = Acceleration::fromVelocityAndTime(new Velocity(50, 'm/s'), new Time(5, 's'));
$a1->toUnit('m/s²'); // 10

// Acceleration from Length and Time squared (length / time²)
$a2 = Acceleration::fromLengthAndTime(new Length(100, 'm'), new Time(10, 's'));
$a2->toUnit('m/s²'); // 1

Acceleration::fromLengthAndTime() divides the length by the square of the time and throws InvalidArgumentException if the time is zero.