nd4j-common/src/main/java/org/nd4j/linalg/util/BigDecimalMath.java
static public BigDecimal modpi(BigDecimal x) {
        /* write x= pi*k+r with the precision in r defined by the precision of x and not
         * compromised by the precision of pi, so the ulp of pi*k should match the ulp of x.
         * First getFloat a guess of k to figure out how many digits of pi are needed.
         */
        int k = (int) (x.doubleValue() / Math.PI);
        /* want to have err(pi*k)< err(x)=x.ulp/2, so err(pi) = err(x)/(2k) with two safety digits
         */


        double errpi;


        if (k != 0) {
            errpi = 0.5 * Math.abs(x.ulp().doubleValue() / k);
        } else {
            errpi = 0.5 * Math.abs(x.ulp().doubleValue());
        }
        MathContext mc = new MathContext(2 + err2prec(3.1416, errpi));
        BigDecimal onepi = pi(mc);
        BigDecimal pihalf = onepi.divide(new BigDecimal(2));
        /* Delegate the actual operation to the BigDecimal class, which may return
         * a negative value of x was negative .
         */
        BigDecimal res = x.remainder(onepi);


        if (res.compareTo(pihalf) > 0) {
            res = res.subtract(onepi);
        } else if (res.compareTo(pihalf.negate()) < 0) {
            res = res.add(onepi);
        }
        /* The actual precision is set by the input value, its absolute value of x.ulp()/2.
         */
        mc = new MathContext(err2prec(res.doubleValue(), x.ulp().doubleValue() / 2.));


        return res.round(mc);


    }
static public BigDecimal modpi(BigDecimal x) {
        /* write x= pi*k+r with the precision in r defined by the precision of x and not
         * compromised by the precision of pi, so the ulp of pi*k should match the ulp of x.
         * First getFloat a guess of k to figure out how many digits of pi are needed.
         */
        int k = (int) (x.doubleValue() / Math.PI);
        /* want to have err(pi*k)< err(x)=x.ulp/2, so err(pi) = err(x)/(2k) with two safety digits
         */


        double errpi;


        if (k != 0) {
            errpi = 0.5 * Math.abs(x.ulp().doubleValue() / k);
        } else {
            errpi = 0.5 * Math.abs(x.ulp().doubleValue());
        }
        MathContext mc = new MathContext(2 + err2prec(3.1416, errpi));
        BigDecimal onepi = pi(mc);
        BigDecimal pihalf = onepi.divide(new BigDecimal(2));
        /* Delegate the actual operation to the BigDecimal class, which may return
         * a negative value of x was negative .
         */
        BigDecimal res = x.remainder(onepi);


        if (res.compareTo(pihalf) > 0) {
            res = res.subtract(onepi);
        } else if (res.compareTo(pihalf.negate()) < 0) {
            res = res.add(onepi);
        }
        /* The actual precision is set by the input value, its absolute value of x.ulp()/2.
         */
        mc = new MathContext(err2prec(res.doubleValue(), x.ulp().doubleValue() / 2.));


        return res.round(mc);


    }
static public BigDecimal modpi ( BigDecimal x ) { /* write x= pi*k+r with the precision in r defined by the precision of x and not
         * compromised by the precision of pi, so the ulp of pi*k should match the ulp of x.
         * First getFloat a guess of k to figure out how many digits of pi are needed.
         */ int k = ( int ) ( x . doubleValue ( ) / Math . PI ) ; /* want to have err(pi*k)< err(x)=x.ulp/2, so err(pi) = err(x)/(2k) with two safety digits
         */ double errpi ; if ( k != 0 ) { errpi = 0.5 * Math . abs ( x . ulp ( ) . doubleValue ( ) / k ) ; } else { errpi = 0.5 * Math . abs ( x . ulp ( ) . doubleValue ( ) ) ; } MathContext mc = new MathContext ( 2 + err2prec ( 3.1416 , errpi ) ) ; BigDecimal onepi = pi ( mc ) ; BigDecimal pihalf = onepi . divide ( new BigDecimal ( 2 ) ) ; /* Delegate the actual operation to the BigDecimal class, which may return
         * a negative value of x was negative .
         */ BigDecimal res = x . remainder ( onepi ) ; if ( res . compareTo ( pihalf ) > 0 ) { res = res . subtract ( onepi ) ; } else if ( res . compareTo ( pihalf . negate ( ) ) < 0 ) { res = res . add ( onepi ) ; } /* The actual precision is set by the input value, its absolute value of x.ulp()/2.
         */ mc = new MathContext ( err2prec ( res . doubleValue ( ) , x . ulp ( ) . doubleValue ( ) / 2. ) ) ; return res . round ( mc ) ; }
Reduce value to the interval [-Pi/2,Pi/2].

@param x The original value
@return The value modulo pi, shifted to the interval from -Pi/2 to Pi/2.
Reduce value to the interval [ - Pi / 2 Pi / 2 ] .