package org.fisco.bcos.web3j.abi.datatypes; import java.math.BigInteger; /** Common fixed-point type properties. */ public abstract class FixedPointType extends NumericType { static final int DEFAULT_BIT_LENGTH = MAX_BIT_LENGTH >> 1; public FixedPointType(String typePrefix, int mBitSize, int nBitSize, BigInteger value) { super(typePrefix + mBitSize + "x" + nBitSize, value); if (!valid(mBitSize, nBitSize, value)) { throw new UnsupportedOperationException( "Bitsize must be 8 bit aligned, and in range 0 < bitSize <= 256"); } } boolean valid(int mBitSize, int nBitSize, BigInteger value) { return isValidBitSize(mBitSize, nBitSize) && isValidBitCount(mBitSize, nBitSize, value); } static boolean isValidBitSize(int mBitSize, int nBitSize) { int bitSize = mBitSize + nBitSize; return mBitSize % 8 == 0 && nBitSize % 8 == 0 && bitSize > 0 && bitSize <= MAX_BIT_LENGTH; } private static boolean isValidBitCount(int mBitSize, int nBitSize, BigInteger value) { return value.bitCount() <= mBitSize + nBitSize; } static BigInteger convert(BigInteger m, BigInteger n) { return convert(DEFAULT_BIT_LENGTH, DEFAULT_BIT_LENGTH, m, n); } static BigInteger convert(int mBitSize, int nBitSize, BigInteger m, BigInteger n) { BigInteger mPadded = m.shiftLeft(nBitSize); int nBitLength = n.bitLength(); // find next multiple of 4 int shift = (nBitLength + 3) & ~0x03; return mPadded.or(n.shiftLeft(nBitSize - shift)); } }