import { Exponent , PositiveExponent } from "../exponent" ; import { addExponents , divideExponents , multiplyExponents } from "../exponent/exponentValueArithmetic" ; import { AllowedExponents , DivideUnits , DivisorUnit , ExponentiateUnit , MultiplicandUnit , MultiplyUnits , NthRootUnit , RadicandUnit , SymbolAndExponent , Unit , UnitWithSymbols , } from "./unitTypeArithmetic" ; export function dimension < Dim extends string > ( dim , symbol ? ) { return { [ dim ] : [ symbol || dim , "1" ] } as any ; } export function multiplyUnits < L extends Unit , R extends MultiplicandUnit < L > > ( left , right ) { const result = { } ; for ( const dimension in left ) { const symbolAndExponent = copySymbolAndExponent ( left , dimension ) ; if ( symbolAndExponent !== undefined && symbolAndExponent [ 1 ] !== "0" ) { result [ dimension ] = symbolAndExponent ; } } for ( const dimension in right ) { const symbolAndExponent = copySymbolAndExponent ( right , dimension ) ; if ( symbolAndExponent === undefined ) { continue ; } const [ , exponent ] = symbolAndExponent ; const resultValue = result [ dimension ] ; if ( resultValue !== undefined ) { const newExponent = addExponents ( resultValue [ 1 ] , exponent ) ; if ( newExponent === "0" ) { delete result [ dimension ] ; } else { resultValue [ 1 ] = newExponent ; } } else if ( exponent !== "0" ) { result [ dimension ] = symbolAndExponent ; } } return result as any ; } function copySymbolAndExponent ( unit , dimension ) { const result = unit [ dimension ] ; if ( result === undefined ) { return undefined ; } const [ symbol , exponent ] = result ; return [ symbol , exponent ] ; } export function divideUnits < L extends Unit , R extends DivisorUnit < L > > ( left , right ) { const rightInverse = exponentiateUnit ( right , "-1" ) as any ; return multiplyUnits ( left , rightInverse ) as any ; } export function exponentiateUnit < U extends Unit , N extends AllowedExponents < U > > ( unit , power ) { return expAndRootImpl ( unit , exponent => multiplyExponents ( exponent , power ) ) ; } export function nthRootUnit < U extends RadicandUnit < N > , N extends PositiveExponent > ( unit , root ) { return expAndRootImpl ( unit , exponent => divideExponents ( exponent , root ) ) ; } function expAndRootImpl ( unit , updateExponent ) { const result = { } ; for ( const dimension in unit ) { const symbolAndExponent = unit [ dimension ] ; if ( symbolAndExponent === undefined ) { continue ; } const [ symbol , exponent ] = symbolAndExponent ; const newExponent = updateExponent ( exponent ) ; if ( newExponent !== "0" ) { result [ dimension ] = [ symbol , newExponent ] ; } } return result ; }