import BigNumber , { bn } from '../big-number' ; import * as logExp from './log-exp' ; export const ZERO = bn ( 0 ) ; export const ONE = bn ( '1000000000000000000' ) ; export const MAX_POW_RELATIVE_ERROR = bn ( 10000 ) ; export const MIN_POW_BASE_FREE_EXPONENT = bn ( '700000000000000000' ) ; export const add = ( a , b ) : BigNumber => { return a . plus ( b ) ; } ; export const sub = ( a , b ) : BigNumber => { if ( b . gt ( a ) ) { throw new Error ( 'SUB_OVERFLOW' ) ; } return a . minus ( b ) ; } ; export const mulDown = ( a , b ) : BigNumber => { return a . times ( b ) . idiv ( ONE ) ; } ; export const mulUp = ( a , b ) : BigNumber => { const product = a . times ( b ) ; if ( product . isZero ( ) ) { return product ; } else { return product . minus ( bn ( 1 ) ) . idiv ( ONE ) . plus ( bn ( 1 ) ) ; } } ; export const divDown = ( a , b ) : BigNumber => { if ( b . isZero ( ) ) { throw new Error ( 'ZERO_DIVISION' ) ; } if ( a . isZero ( ) ) { return a ; } else { return a . times ( ONE ) . idiv ( b ) ; } } ; export const divUp = ( a , b ) : BigNumber => { if ( b . isZero ( ) ) { throw new Error ( 'ZERO_DIVISION' ) ; } if ( a . isZero ( ) ) { return a ; } else { return a . times ( ONE ) . minus ( bn ( 1 ) ) . idiv ( b ) . plus ( bn ( 1 ) ) ; } } ; export const powDown = ( x , y ) : BigNumber => { const raw = logExp . pow ( x , y ) ; const maxError = add ( mulUp ( raw , MAX_POW_RELATIVE_ERROR ) , bn ( 1 ) ) ; if ( raw . lt ( maxError ) ) { return bn ( 0 ) ; } else { return sub ( raw , maxError ) ; } } ; export const powUp = ( x , y ) : BigNumber => { const raw = logExp . pow ( x , y ) ; const maxError = add ( mulUp ( raw , MAX_POW_RELATIVE_ERROR ) , bn ( 1 ) ) ; return add ( raw , maxError ) ; } ; export const complement = ( x ) : BigNumber => { return x . lt ( ONE ) ? ONE . minus ( x ) : bn ( 0 ) ; } ;