<commit_before><?php
/**
 * Mathematician
 *
 * @author      <NAME> (Rican7)
 * @copyright   2014 <NAME>
 * @license     MIT
 * @version     0.1.0
 */

namespace Mathematician\Integer\Adapter;

use Mathematician\Exception\InvalidNumberException;
use Mathematician\Exception\InvalidPrecisionException;
use Mathematician\Exception\InvalidTypeException;

/**
 * Gmp
 *
 * @uses AbstractAdapter
 * @uses AdapterInterface
 * @package Mathematician\Integer\Adapter
 */
class Gmp extends AbstractAdapter implements AdapterInterface
{

    /**
     * Constants
     */

    /**
     * The name of the GMP resource type
     *
     * @const string
     */
    const GMP_RESOURCE_TYPE_NAME = 'GMP integer';


    /**
     * Methods
     */

    /**
     * Constructor
     *
     * @param mixed $number
     * @param int $radix
     * @access public
     */
    public function __construct($number, $radix = 0)
    {
        // The PHP "gmp" extension doesn't support floats :/
        if (is_float($number)) {
            throw new InvalidTypeException(
                'The GMP extension doesn\'t support float values.'
                .' Attempt to build a '. get_class($this) .' instance with a float value: '. $number
            );
        } elseif (static::isGmpResource($number)) {
            $this->raw_value = $number;
        } else {
            $this->raw_value = gmp_init($number, (int) $radix);
        }

        // Verify the value actually makes sense
        if (false === $this->raw_value) {
            throw new InvalidNumberException(
                'GMP failed to initialize correctly with your value: '. $number
            );
        }
    }

    /**
     * Create an instance of a number adapter
     *
     * @param mixed $number
     * @param int $radix
     * @static
     * @access public
     * @return self
     */
    public static function factory($number, $radix = null)
    {
        return new static($number, $radix);
    }

    /**
     * Check if a given value is a GMP resource
     *
     * @param mixed $number
     * @static
     * @access public
     * @return boolean
     */
    public static function isGmpResource($number)
    {
        if (is_resource($number)
            && get_resource_type($number) == static::GMP_RESOURCE_TYPE_NAME) {

            return true;
        }

        return false;
    }

    /**
     * Compare numbers
     *
     * @param mixed $number
     * @access public
     * @return int
     */
    public function compareTo($number)
    {
        return gmp_cmp(
            $this->getRawValue(),
            static::upgradeParam($number)->getRawValue()
        );
    }

    /**
     * Check if the number is negative
     *
     * @access public
     * @return boolean
     */
    public function isNegative()
    {
        return ($this->compareTo(0) === -1);
    }

    /**
     * Get the absolute value
     *
     * @access public
     * @return self
     */
    public function abs()
    {
        $result = gmp_abs(
            $this->getRawValue()
        );

        return static::factory($result);
    }

    /**
     * Add numbers
     *
     * @param mixed $number
     * @access public
     * @return self
     */
    public function add($number)
    {
        $result = gmp_add(
            $this->getRawValue(),
            static::upgradeParam($number)->getRawValue()
        );

        return static::factory($result);
    }

    /**<commit_msg>New `twosComplement()` method in the Gmp adapter<commit_after><?php
/**
 * Mathematician
 *
 * @author      <NAME> (Rican7)
 * @copyright   2014 <NAME>
 * @license     MIT
 * @version     0.1.0
 */

namespace Mathematician\Integer\Adapter;

use Mathematician\Exception\InvalidNumberException;
use Mathematician\Exception\InvalidPrecisionException;
use Mathematician\Exception\InvalidTypeException;

/**
 * Gmp
 *
 * @uses AbstractAdapter
 * @uses AdapterInterface
 * @package Mathematician\Integer\Adapter
 */
class Gmp extends AbstractAdapter implements AdapterInterface
{

    /**
     * Constants
     */

    /**
     * The name of the GMP resource type
     *
     * @const string
     */
    const GMP_RESOURCE_TYPE_NAME = 'GMP integer';


    /**
     * Methods
     */

    /**
     * Constructor
     *
     * @param mixed $number
     * @param int $radix
     * @access public
     */
    public function __construct($number, $radix = 0)
    {
        // The PHP "gmp" extension doesn't support floats :/
        if (is_float($number)) {
            throw new InvalidTypeException(
                'The GMP extension doesn\'t support float values.'
                .' Attempt to build a '. get_class($this) .' instance with a float value: '. $number
            );
        } elseif (static::isGmpResource($number)) {
            $this->raw_value = $number;
        } else {
            $this->raw_value = gmp_init($number, (int) $radix);
        }

        // Verify the value actually makes sense
        if (false === $this->raw_value) {
            throw new InvalidNumberException(
                'GMP failed to initialize correctly with your value: '. $number
            );
        }
    }

    /**
     * Create an instance of a number adapter
     *
     * @param mixed $number
     * @param int $radix
     * @static
     * @access public
     * @return self
     */
    public static function factory($number, $radix = null)
    {
        return new static($number, $radix);
    }

    /**
     * Check if a given value is a GMP resource
     *
     * @param mixed $number
     * @static
     * @access public
     * @return boolean
     */
    public static function isGmpResource($number)
    {
        if (is_resource($number)
            && get_resource_type($number) == static::GMP_RESOURCE_TYPE_NAME) {

            return true;
        }

        return false;
    }

    /**
     * Compare numbers
     *
     * @param mixed $number
     * @access public
     * @return int
     */
    public function compareTo($number)
    {
        return gmp_cmp(
            $this->getRawValue(),
            static::upgradeParam($number)->getRawValue()
        );
    }

    /**
     * Check if the number is negative
     *
     * @access public
     * @return boolean
     */
    public function isNegative()
    {
        return ($this->compareTo(0) === -1);
    }

    /**
     * Get the absolute value
     *
     * @access public
     * @return self
     */
    public function abs()
    {
        $result = gmp_abs(
            $this->getRawValue()
        );

        return static::factory($result);
    }

    /**
     * Get the two's complement of the number, without native signed interpretation
     *
     * @param int $bit_length The number of bits to use in the mask
     * @access public
     * @return self
     */
    public function twosComplement($bit_length = 0)
    {
        if ($this->isNegative()) {
            $abs = $this->abs();

            // Get the bit length
            $min_bit_length = strlen($abs->toString(2)) + 1;

            if ($bit_length < $min_bit_length) {
                $bit_length = $min_bit_length;
            }

            $bit_length_multiple = static::factory(2)->pow($bit_length - 1);

            // Get the one's complement
            $ones_comp = $abs->bitNot()->bitAnd($bit_length_multiple->sub(1));

            // Add our leading 1's with our bit multiple and add 1
            return $ones_comp->add($bit_length_multiple)->add(1);
        }

        return static::factory($this->toString());
    }

    /**
     * Add numbers
     *
     * @param mixed $number
     * @access public
     * @return self
     */
    public function add($number)
    {
        $result = gmp_add(
            $this->getRawValue(),
            static::upgradeParam($number)->getRawValue()
        );

        return static::factory($result);
    }

    /**
{'fraction_non_alphanumeric': 0.11838085539714868, 'fraction_numerical': 0.003946028513238289, 'mean_word_length': 1.7990737442109013, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3004984', 'n_tokens_mistral': 2316, 'n_tokens_neox': 2217, 'n_words': 567}