/** String: size = variable */
 public static int getLength(byte[] b, int offset) {
   int len = arrayToInteger(b, offset);
   return StrictMath.max(0, len) + 4;
 }
  public double nextGaussian() {
    if (__haveNextNextGaussian) {
      __haveNextNextGaussian = false;
      return __nextNextGaussian;
    } else {
      double v1, v2, s;
      do {
        int y;
        int z;
        int a;
        int b;

        if (mti >= N) // generate N words at one time
        {
          int kk;
          final int[] mt = this.mt; // locals are slightly faster
          final int[] mag01 = this.mag01; // locals are slightly faster

          for (kk = 0; kk < N - M; kk++) {
            y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
            mt[kk] = mt[kk + M] ^ (y >>> 1) ^ mag01[y & 0x1];
          }
          for (; kk < N - 1; kk++) {
            y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
            mt[kk] = mt[kk + (M - N)] ^ (y >>> 1) ^ mag01[y & 0x1];
          }
          y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
          mt[N - 1] = mt[M - 1] ^ (y >>> 1) ^ mag01[y & 0x1];

          mti = 0;
        }

        y = mt[mti++];
        y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
        y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
        y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
        y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)

        if (mti >= N) // generate N words at one time
        {
          int kk;
          final int[] mt = this.mt; // locals are slightly faster
          final int[] mag01 = this.mag01; // locals are slightly faster

          for (kk = 0; kk < N - M; kk++) {
            z = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
            mt[kk] = mt[kk + M] ^ (z >>> 1) ^ mag01[z & 0x1];
          }
          for (; kk < N - 1; kk++) {
            z = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
            mt[kk] = mt[kk + (M - N)] ^ (z >>> 1) ^ mag01[z & 0x1];
          }
          z = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
          mt[N - 1] = mt[M - 1] ^ (z >>> 1) ^ mag01[z & 0x1];

          mti = 0;
        }

        z = mt[mti++];
        z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
        z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
        z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
        z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)

        if (mti >= N) // generate N words at one time
        {
          int kk;
          final int[] mt = this.mt; // locals are slightly faster
          final int[] mag01 = this.mag01; // locals are slightly faster

          for (kk = 0; kk < N - M; kk++) {
            a = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
            mt[kk] = mt[kk + M] ^ (a >>> 1) ^ mag01[a & 0x1];
          }
          for (; kk < N - 1; kk++) {
            a = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
            mt[kk] = mt[kk + (M - N)] ^ (a >>> 1) ^ mag01[a & 0x1];
          }
          a = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
          mt[N - 1] = mt[M - 1] ^ (a >>> 1) ^ mag01[a & 0x1];

          mti = 0;
        }

        a = mt[mti++];
        a ^= a >>> 11; // TEMPERING_SHIFT_U(a)
        a ^= (a << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(a)
        a ^= (a << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(a)
        a ^= (a >>> 18); // TEMPERING_SHIFT_L(a)

        if (mti >= N) // generate N words at one time
        {
          int kk;
          final int[] mt = this.mt; // locals are slightly faster
          final int[] mag01 = this.mag01; // locals are slightly faster

          for (kk = 0; kk < N - M; kk++) {
            b = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
            mt[kk] = mt[kk + M] ^ (b >>> 1) ^ mag01[b & 0x1];
          }
          for (; kk < N - 1; kk++) {
            b = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
            mt[kk] = mt[kk + (M - N)] ^ (b >>> 1) ^ mag01[b & 0x1];
          }
          b = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
          mt[N - 1] = mt[M - 1] ^ (b >>> 1) ^ mag01[b & 0x1];

          mti = 0;
        }

        b = mt[mti++];
        b ^= b >>> 11; // TEMPERING_SHIFT_U(b)
        b ^= (b << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(b)
        b ^= (b << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(b)
        b ^= (b >>> 18); // TEMPERING_SHIFT_L(b)

        /* derived from nextDouble documentation in jdk 1.2 docs, see top */
        v1 = 2 * (((((long) (y >>> 6)) << 27) + (z >>> 5)) / (double) (1L << 53)) - 1;
        v2 = 2 * (((((long) (a >>> 6)) << 27) + (b >>> 5)) / (double) (1L << 53)) - 1;
        s = v1 * v1 + v2 * v2;
      } while (s >= 1 || s == 0);
      double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s);
      __nextNextGaussian = v2 * multiplier;
      __haveNextNextGaussian = true;
      return v1 * multiplier;
    }
  }
 /** scales the given number with the provided scale factor */
 private int doScale(int number, double factor) {
   return (int) StrictMath.round(number * factor);
 }