spiceJ/real-time/src/main/java/at/borkowski/spicej/rt/RateCalculator.java
public static Result calculate(float rateBytesPerSecond, int minInterval) {
      BigDecimal B_MIN = BigDecimal.ONE;
      BigDecimal B_MAX = BigDecimal.valueOf(MAX_BYTES_PER_TICK);
      BigDecimal I_MIN = BigDecimal.valueOf(minInterval);
      BigDecimal I_MAX = BigDecimal.valueOf(MAX_INTERVAL_NS);
      BigDecimal Id_MAX = BigDecimal.valueOf(Integer.MAX_VALUE);

      BigDecimal ONEG = BigDecimal.valueOf(NS_PER_S);
      BigDecimal TWO = BigDecimal.valueOf(2);
      BigDecimal E = BigDecimal.valueOf(Math.E);

      BigDecimal R = BigDecimal.valueOf(rateBytesPerSecond).divide(ONEG, SCALE, ROUND);
      BigDecimal I = I_MAX;

      BigDecimal B = R.multiply(I);

      BigDecimal ERROR;
      BigDecimal ERROR_MAX = BigDecimal.valueOf(MAX_ERROR);

      BigDecimal R_set = BigDecimal.valueOf(rateBytesPerSecond).divide(ONEG, SCALE, ROUND);
      BigDecimal R_eff;

      // bytes per I_MAX <= 1
      if (B.compareTo(B_MIN) <= 0) {
         B = BigDecimal.ONE;
         I = B.divide(R, SCALE, ROUND);

         BigDecimal Id = BigDecimal.ONE;
         while (true) {
            while (I.compareTo(I_MAX) > 0) {
               I = I.divide(E, SCALE, ROUND);
               Id = Id.multiply(E);
            }

            if (Id.compareTo(Id_MAX) > 0)
               throw new IllegalArgumentException("rate too low (" + rateBytesPerSecond + "): prescaler too high");

            BigDecimal B_int = BigDecimal.valueOf(B.setScale(0, ROUND).intValueExact());
            BigDecimal I_int = BigDecimal.valueOf(I.setScale(0, ROUND).intValueExact());
            BigDecimal Id_int = BigDecimal.valueOf(Id.setScale(0, ROUND).intValueExact());

            R_eff = B_int.divide(I_int, SCALE, ROUND).divide(Id_int, SCALE, ROUND);
            ERROR = R_eff.divide(R_set, SCALE, ROUND).subtract(BigDecimal.ONE).abs();
            if (ERROR.compareTo(ERROR_MAX) < 0)
               break;

            I = I.multiply(E);
            B = B.multiply(E);
         }

         return new Result(B.setScale(0, ROUND).intValueExact(), Id.setScale(0, ROUND).intValueExact(), I.setScale(0, ROUND).intValueExact());
      } else {
         BigDecimal Id = BigDecimal.ONE;

         while (true) {
            while (I.compareTo(I_MAX) > 0) {
               I = I.divide(E, SCALE, ROUND);
               Id = Id.multiply(E);
            }

            while (B.compareTo(B_MAX) > 0) {
               B = B.divide(TWO, SCALE, ROUND);
               I = I.divide(TWO, SCALE, ROUND);
            }

            if (I.compareTo(BigDecimal.ONE) < 0)
               throw new IllegalArgumentException("rate too high (" + rateBytesPerSecond + "): interval too low");

            BigDecimal B_int = BigDecimal.valueOf(B.setScale(0, ROUND).intValueExact());
            BigDecimal I_int = BigDecimal.valueOf(I.setScale(0, ROUND).intValueExact());
            BigDecimal Id_int = BigDecimal.valueOf(Id.setScale(0, ROUND).intValueExact());

            R_eff = B_int.divide(I_int, SCALE, ROUND).divide(Id_int, SCALE, ROUND);
            ERROR = R_eff.divide(R_set, SCALE, ROUND).subtract(BigDecimal.ONE).abs();
            if (ERROR.compareTo(ERROR_MAX) < 0)
               break;

            I = I.multiply(E);
            B = B.multiply(E);
         }

         if (I.compareTo(I_MIN) < 0)
            throw new IllegalArgumentException("rate too high (" + rateBytesPerSecond + "): interval too low");

         return new Result(B.setScale(0, ROUND).intValueExact(), Id.setScale(0, ROUND).intValueExact(), I.setScale(0, ROUND).intValueExact());
      }
   }
public static Result calculate(float rateBytesPerSecond, int minInterval) {
      BigDecimal B_MIN = BigDecimal.ONE;
      BigDecimal B_MAX = BigDecimal.valueOf(MAX_BYTES_PER_TICK);
      BigDecimal I_MIN = BigDecimal.valueOf(minInterval);
      BigDecimal I_MAX = BigDecimal.valueOf(MAX_INTERVAL_NS);
      BigDecimal Id_MAX = BigDecimal.valueOf(Integer.MAX_VALUE);

      BigDecimal ONEG = BigDecimal.valueOf(NS_PER_S);
      BigDecimal TWO = BigDecimal.valueOf(2);
      BigDecimal E = BigDecimal.valueOf(Math.E);

      BigDecimal R = BigDecimal.valueOf(rateBytesPerSecond).divide(ONEG, SCALE, ROUND);
      BigDecimal I = I_MAX;

      BigDecimal B = R.multiply(I);

      BigDecimal ERROR;
      BigDecimal ERROR_MAX = BigDecimal.valueOf(MAX_ERROR);

      BigDecimal R_set = BigDecimal.valueOf(rateBytesPerSecond).divide(ONEG, SCALE, ROUND);
      BigDecimal R_eff;

      // bytes per I_MAX <= 1
      if (B.compareTo(B_MIN) <= 0) {
         B = BigDecimal.ONE;
         I = B.divide(R, SCALE, ROUND);

         BigDecimal Id = BigDecimal.ONE;
         while (true) {
            while (I.compareTo(I_MAX) > 0) {
               I = I.divide(E, SCALE, ROUND);
               Id = Id.multiply(E);
            }

            if (Id.compareTo(Id_MAX) > 0)
               throw new IllegalArgumentException("rate too low (" + rateBytesPerSecond + "): prescaler too high");

            BigDecimal B_int = BigDecimal.valueOf(B.setScale(0, ROUND).intValueExact());
            BigDecimal I_int = BigDecimal.valueOf(I.setScale(0, ROUND).intValueExact());
            BigDecimal Id_int = BigDecimal.valueOf(Id.setScale(0, ROUND).intValueExact());

            R_eff = B_int.divide(I_int, SCALE, ROUND).divide(Id_int, SCALE, ROUND);
            ERROR = R_eff.divide(R_set, SCALE, ROUND).subtract(BigDecimal.ONE).abs();
            if (ERROR.compareTo(ERROR_MAX) < 0)
               break;

            I = I.multiply(E);
            B = B.multiply(E);
         }

         return new Result(B.setScale(0, ROUND).intValueExact(), Id.setScale(0, ROUND).intValueExact(), I.setScale(0, ROUND).intValueExact());
      } else {
         BigDecimal Id = BigDecimal.ONE;

         while (true) {
            while (I.compareTo(I_MAX) > 0) {
               I = I.divide(E, SCALE, ROUND);
               Id = Id.multiply(E);
            }

            while (B.compareTo(B_MAX) > 0) {
               B = B.divide(TWO, SCALE, ROUND);
               I = I.divide(TWO, SCALE, ROUND);
            }

            if (I.compareTo(BigDecimal.ONE) < 0)
               throw new IllegalArgumentException("rate too high (" + rateBytesPerSecond + "): interval too low");

            BigDecimal B_int = BigDecimal.valueOf(B.setScale(0, ROUND).intValueExact());
            BigDecimal I_int = BigDecimal.valueOf(I.setScale(0, ROUND).intValueExact());
            BigDecimal Id_int = BigDecimal.valueOf(Id.setScale(0, ROUND).intValueExact());

            R_eff = B_int.divide(I_int, SCALE, ROUND).divide(Id_int, SCALE, ROUND);
            ERROR = R_eff.divide(R_set, SCALE, ROUND).subtract(BigDecimal.ONE).abs();
            if (ERROR.compareTo(ERROR_MAX) < 0)
               break;

            I = I.multiply(E);
            B = B.multiply(E);
         }

         if (I.compareTo(I_MIN) < 0)
            throw new IllegalArgumentException("rate too high (" + rateBytesPerSecond + "): interval too low");

         return new Result(B.setScale(0, ROUND).intValueExact(), Id.setScale(0, ROUND).intValueExact(), I.setScale(0, ROUND).intValueExact());
      }
   }
public static Result calculate ( float rateBytesPerSecond , int minInterval ) { BigDecimal B_MIN = BigDecimal . ONE ; BigDecimal B_MAX = BigDecimal . valueOf ( MAX_BYTES_PER_TICK ) ; BigDecimal I_MIN = BigDecimal . valueOf ( minInterval ) ; BigDecimal I_MAX = BigDecimal . valueOf ( MAX_INTERVAL_NS ) ; BigDecimal Id_MAX = BigDecimal . valueOf ( Integer . MAX_VALUE ) ; BigDecimal ONEG = BigDecimal . valueOf ( NS_PER_S ) ; BigDecimal TWO = BigDecimal . valueOf ( 2 ) ; BigDecimal E = BigDecimal . valueOf ( Math . E ) ; BigDecimal R = BigDecimal . valueOf ( rateBytesPerSecond ) . divide ( ONEG , SCALE , ROUND ) ; BigDecimal I = I_MAX ; BigDecimal B = R . multiply ( I ) ; BigDecimal ERROR ; BigDecimal ERROR_MAX = BigDecimal . valueOf ( MAX_ERROR ) ; BigDecimal R_set = BigDecimal . valueOf ( rateBytesPerSecond ) . divide ( ONEG , SCALE , ROUND ) ; BigDecimal R_eff ; // bytes per I_MAX <= 1 if ( B . compareTo ( B_MIN ) <= 0 ) { B = BigDecimal . ONE ; I = B . divide ( R , SCALE , ROUND ) ; BigDecimal Id = BigDecimal . ONE ; while ( true ) { while ( I . compareTo ( I_MAX ) > 0 ) { I = I . divide ( E , SCALE , ROUND ) ; Id = Id . multiply ( E ) ; } if ( Id . compareTo ( Id_MAX ) > 0 ) throw new IllegalArgumentException ( "rate too low (" + rateBytesPerSecond + "): prescaler too high" ) ; BigDecimal B_int = BigDecimal . valueOf ( B . setScale ( 0 , ROUND ) . intValueExact ( ) ) ; BigDecimal I_int = BigDecimal . valueOf ( I . setScale ( 0 , ROUND ) . intValueExact ( ) ) ; BigDecimal Id_int = BigDecimal . valueOf ( Id . setScale ( 0 , ROUND ) . intValueExact ( ) ) ; R_eff = B_int . divide ( I_int , SCALE , ROUND ) . divide ( Id_int , SCALE , ROUND ) ; ERROR = R_eff . divide ( R_set , SCALE , ROUND ) . subtract ( BigDecimal . ONE ) . abs ( ) ; if ( ERROR . compareTo ( ERROR_MAX ) < 0 ) break ; I = I . multiply ( E ) ; B = B . multiply ( E ) ; } return new Result ( B . setScale ( 0 , ROUND ) . intValueExact ( ) , Id . setScale ( 0 , ROUND ) . intValueExact ( ) , I . setScale ( 0 , ROUND ) . intValueExact ( ) ) ; } else { BigDecimal Id = BigDecimal . ONE ; while ( true ) { while ( I . compareTo ( I_MAX ) > 0 ) { I = I . divide ( E , SCALE , ROUND ) ; Id = Id . multiply ( E ) ; } while ( B . compareTo ( B_MAX ) > 0 ) { B = B . divide ( TWO , SCALE , ROUND ) ; I = I . divide ( TWO , SCALE , ROUND ) ; } if ( I . compareTo ( BigDecimal . ONE ) < 0 ) throw new IllegalArgumentException ( "rate too high (" + rateBytesPerSecond + "): interval too low" ) ; BigDecimal B_int = BigDecimal . valueOf ( B . setScale ( 0 , ROUND ) . intValueExact ( ) ) ; BigDecimal I_int = BigDecimal . valueOf ( I . setScale ( 0 , ROUND ) . intValueExact ( ) ) ; BigDecimal Id_int = BigDecimal . valueOf ( Id . setScale ( 0 , ROUND ) . intValueExact ( ) ) ; R_eff = B_int . divide ( I_int , SCALE , ROUND ) . divide ( Id_int , SCALE , ROUND ) ; ERROR = R_eff . divide ( R_set , SCALE , ROUND ) . subtract ( BigDecimal . ONE ) . abs ( ) ; if ( ERROR . compareTo ( ERROR_MAX ) < 0 ) break ; I = I . multiply ( E ) ; B = B . multiply ( E ) ; } if ( I . compareTo ( I_MIN ) < 0 ) throw new IllegalArgumentException ( "rate too high (" + rateBytesPerSecond + "): interval too low" ) ; return new Result ( B . setScale ( 0 , ROUND ) . intValueExact ( ) , Id . setScale ( 0 , ROUND ) . intValueExact ( ) , I . setScale ( 0 , ROUND ) . intValueExact ( ) ) ; } }
Performs a calculation with the given minimal interval. See
{@link RateCalculator} for details.

@param rateBytesPerSecond
The rate in bytes per second to target
@param minInterval
The minimal interval in nanoseconds.
@return the calculation result
Performs a calculation with the given minimal interval . See { @link RateCalculator } for details .