While Univerto maintains precision through its internal fraction-based system, JavaScript’s native number type has limitations. For applications requiring arbitrary precision or working with extremely large/small numbers, you can integrate Univerto with high-precision arithmetic libraries.
Why Use Arbitrary Precision?
JavaScript’s number type (IEEE 754 double-precision) has constraints:
- Maximum safe integer:
2^53 - 1 (9,007,199,254,740,991)
- Precision: ~15-17 significant decimal digits
- Range: ±1.7976931348623157 × 10^308
You might need arbitrary precision for:
- Financial calculations: Exact decimal arithmetic for monetary values
- Scientific computing: Measurements with many significant figures
- Cryptography: Very large integer operations
- Astronomy/physics: Extremely large or small values
The convertToFraction() Method
Univerto provides convertToFraction() to expose the internal fraction representation:
import { TIME_UNIT, TimeUnitConverter } from 'univerto/time'
const fraction = TimeUnitConverter.from(1, TIME_UNIT.HOUR)
.to(TIME_UNIT.MILLISECOND)
.convertToFraction()
console.log(fraction)
// { numerator: 3600000, denominator: 1 }
This returns a simple object:
interface Fraction {
numerator: number
denominator: number
}
You can pass these values to any arbitrary-precision library to perform the final division with the precision you need.
Integration with decimal.js
decimal.js is a popular arbitrary-precision library for JavaScript.
Installation
Basic Usage
import { TIME_UNIT, TimeUnitConverter } from 'univerto/time'
import { Decimal } from 'decimal.js'
// Get the fraction from Univerto
const fraction = TimeUnitConverter.from(1, TIME_UNIT.HOUR)
.to(TIME_UNIT.MILLISECOND)
.convertToFraction()
// Perform high-precision division
const result = new Decimal(fraction.numerator)
.div(fraction.denominator)
console.log(result.toString()) // "3600000"
Complex Example: Nanosecond Precision
import { TIME_UNIT, TimeUnitConverter } from 'univerto/time'
import { Decimal } from 'decimal.js'
// Configure decimal.js for high precision
Decimal.set({ precision: 50 })
// Convert with extreme precision requirements
const fraction = TimeUnitConverter.from(1.123456789, TIME_UNIT.NANOSECOND)
.to(TIME_UNIT.HOUR)
.convertToFraction()
const hours = new Decimal(fraction.numerator)
.div(fraction.denominator)
console.log(hours.toString())
// Maintains precision beyond JavaScript's native capabilities
Working with Large Values
import { DATA_UNIT, DataUnitConverter } from 'univerto/data'
import { Decimal } from 'decimal.js'
// Convert petabytes to bits (very large number)
const fraction = DataUnitConverter.from(1, DATA_UNIT.PETABYTE)
.to(DATA_UNIT.BIT)
.convertToFraction()
const bits = new Decimal(fraction.numerator)
.div(fraction.denominator)
console.log(bits.toExponential())
// "9e+15" - safely handles values beyond MAX_SAFE_INTEGER
Integration with Other Libraries
The convertToFraction() method works with any arbitrary-precision library.
Big.js
Big.js is a smaller, simpler alternative to decimal.js.
import { MASS_UNIT, MassUnitConverter } from 'univerto/mass'
import Big from 'big.js'
const fraction = MassUnitConverter.from(1.5, MASS_UNIT.KILOGRAM)
.to(MASS_UNIT.GRAM)
.convertToFraction()
const grams = new Big(fraction.numerator)
.div(fraction.denominator)
console.log(grams.toString()) // "1500"
bignumber.js
bignumber.js provides similar functionality.
import { LENGTH_UNIT, LengthUnitConverter } from 'univerto/length'
import { BigNumber } from 'bignumber.js'
const fraction = LengthUnitConverter.from(100, LENGTH_UNIT.KILOMETER)
.to(LENGTH_UNIT.METER)
.convertToFraction()
const meters = new BigNumber(fraction.numerator)
.div(fraction.denominator)
console.log(meters.toString()) // "100000"
Native BigInt (for integers only)
For integer-only operations, you can use JavaScript’s native BigInt:
import { TIME_UNIT, TimeUnitConverter } from 'univerto/time'
const fraction = TimeUnitConverter.from(1000, TIME_UNIT.SECOND)
.to(TIME_UNIT.MILLISECOND)
.convertToFraction()
// Only use BigInt when denominator is 1 (integer result)
if (fraction.denominator === 1) {
const result = BigInt(fraction.numerator)
console.log(result.toString()) // "1000000"
} else {
// Handle fractional results with a library
}
BigInt cannot represent fractional values. Only use it when you’re certain the result will be an integer, or when you can handle the numerator and denominator separately.
When to Use convert() vs convertToFraction()
Use convert() when:
- Working with typical numeric ranges (within JavaScript’s safe integer limit)
- Performance is critical (native numbers are faster)
- The built-in precision (15-17 significant digits) is sufficient
- Integrating with APIs/libraries that expect standard numbers
import { SPEED_UNIT, SpeedUnitConverter } from 'univerto/speed'
// Standard usage - convert() is fine
const mph = SpeedUnitConverter.from(100, SPEED_UNIT.KILOMETER_PER_HOUR)
.to(SPEED_UNIT.MILE_PER_HOUR)
.convert()
Use convertToFraction() when:
- Dealing with very large or very small numbers
- Requiring more than 15-17 significant digits of precision
- Performing financial calculations requiring exact decimal arithmetic
- Chaining multiple operations where precision loss could compound
- Interfacing with systems that work with rational numbers
import { VOLUME_UNIT, VolumeUnitConverter } from 'univerto/volume'
import { Decimal } from 'decimal.js'
// High-precision scenario
const fraction = VolumeUnitConverter.from(1/3, VOLUME_UNIT.LITER)
.to(VOLUME_UNIT.MILLILITER)
.convertToFraction()
const ml = new Decimal(fraction.numerator).div(fraction.denominator)
Best Practices
1. Choose the Right Library
- decimal.js: Full-featured, configurable precision, slower
- Big.js: Smaller, simpler, faster, less configurable
- bignumber.js: Similar to Big.js with different API
- Native BigInt: Fastest, but integers only
import { Decimal } from 'decimal.js'
// Set precision based on your needs
Decimal.set({
precision: 50, // Significant digits
rounding: Decimal.ROUND_HALF_UP
})
3. Defer Division Until the End
If you’re performing multiple operations, keep values as fractions:
import { TIME_UNIT, TimeUnitConverter } from 'univerto/time'
import { Decimal } from 'decimal.js'
// Get fraction, perform additional operations, then divide once
const fraction = TimeUnitConverter.from(100, TIME_UNIT.SECOND)
.to(TIME_UNIT.MILLISECOND)
.convertToFraction()
// Additional operations on numerator/denominator
const adjustedNumerator = fraction.numerator * 2
// Single final division
const result = new Decimal(adjustedNumerator).div(fraction.denominator)
4. Handle Edge Cases
const fraction = converter.convertToFraction()
if (fraction.denominator === 0) {
throw new Error('Division by zero')
}
if (!Number.isFinite(fraction.numerator) || !Number.isFinite(fraction.denominator)) {
throw new Error('Invalid fraction values')
}
const result = new Decimal(fraction.numerator).div(fraction.denominator)
Real-World Use Cases
Financial Application
import { VOLUME_UNIT, VolumeUnitConverter } from 'univerto/volume'
import { Decimal } from 'decimal.js'
Decimal.set({ precision: 10, rounding: Decimal.ROUND_HALF_UP })
// Precise billing for liquid volume
const pricePerLiter = new Decimal('3.99')
const fraction = VolumeUnitConverter.from(500, VOLUME_UNIT.MILLILITER)
.to(VOLUME_UNIT.LITER)
.convertToFraction()
const liters = new Decimal(fraction.numerator).div(fraction.denominator)
const totalCost = liters.mul(pricePerLiter)
console.log(totalCost.toFixed(2)) // "1.995" → rounds to "2.00"
Scientific Measurement
import { LENGTH_UNIT, LengthUnitConverter } from 'univerto/length'
import { Decimal } from 'decimal.js'
Decimal.set({ precision: 100 })
// Astronomical distance with extreme precision
const fraction = LengthUnitConverter.from(1e-15, LENGTH_UNIT.METER)
.to(LENGTH_UNIT.NANOMETER)
.convertToFraction()
const nanometers = new Decimal(fraction.numerator).div(fraction.denominator)
console.log(nanometers.toExponential(50))
Summary
- Use
convertToFraction() to access Univerto’s internal fraction representation
- Integrate with decimal.js, Big.js, bignumber.js, or native BigInt for arbitrary precision
- Choose
convert() for standard use cases, convertToFraction() when precision is critical
- Configure your precision library appropriately for your use case
- Keep values as fractions as long as possible before final division
By combining Univerto’s precision-preserving conversions with arbitrary-precision arithmetic libraries, you can handle any numeric requirement with confidence.