public NetBigInteger Multiply(
                NetBigInteger val)
            {
                if (m_sign == 0 || val.m_sign == 0)
                    return Zero;

                if (val.QuickPow2Check()) // val is power of two
                {
                    NetBigInteger result = ShiftLeft(val.Abs().BitLength - 1);
                    return val.m_sign > 0 ? result : result.Negate();
                }

                if (QuickPow2Check()) // this is power of two
                {
                    NetBigInteger result = val.ShiftLeft(Abs().BitLength - 1);
                    return m_sign > 0 ? result : result.Negate();
                }

                int maxBitLength = BitLength + val.BitLength;
                int resLength = (maxBitLength + BitsPerInt - 1) / BitsPerInt;

                int[] res = new int[resLength];

                if (val == this)
                {
                    Square(res, m_magnitude);
                }
                else
                {
                    Multiply(res, m_magnitude, val.m_magnitude);
                }

                return new NetBigInteger(m_sign * val.m_sign, res, true);
            }