import type Decimal from "break_infinity.js" ; import { EngineeringNotation } from "./engineering" ; import { toEngineering } from "./utils" ; export class CustomNotation extends EngineeringNotation { private readonly letters : string [ ] | string ; private readonly mantissaExponentSeparator : string ; private readonly separator : string ; public constructor ( letters , mantissaExponentSeparator = "" , separator = "" ) { if ( letters . length < 2 ) { throw new Error ( "The supplied letter sequence must contain at least 2 letters" ) ; } super ( ) ; this . letters = letters ; this . mantissaExponentSeparator = mantissaExponentSeparator ; this . separator = separator ; } public get name ( ) : string { return "Custom" ; } public formatDecimal ( value , places ) { const engineering = toEngineering ( value ) ; const mantissa = engineering . mantissa . toFixed ( places ) ; return mantissa + this . mantissaExponentSeparator + this . transcribe ( engineering . exponent ) . join ( this . separator ) ; } private transcribe ( exponent ) { let normalizedExponent = exponent / 3 ; const base = this . letters . length ; if ( normalizedExponent <= base ) { return [ this . letters [ normalizedExponent - 1 ] ] ; } const letters = [ ] ; while ( normalizedExponent > base ) { const remainder = normalizedExponent % base ; const letterIndex = ( remainder === 0 ? base : remainder ) - 1 ; letters . push ( this . letters [ letterIndex ] ) ; normalizedExponent = ( normalizedExponent - remainder ) / base ; if ( remainder === 0 ) { normalizedExponent -- ; } } letters . push ( this . letters [ normalizedExponent - 1 ] ) ; return letters . reverse ( ) ; } }