1: <?php
2: /**
3: * Hard type support
4: * For when you absolutely want to know what you are getting
5: *
6: * @author Ashley Kitson <akitson@zf4.biz>
7: * @copyright Ashley Kitson, UK, 2014
8: * @licence GPL V3 or later : http://www.gnu.org/licenses/gpl.html
9: */
10:
11: namespace chippyash\Type\Number;
12:
13: use chippyash\Type\AbstractType;
14: use chippyash\Type\Interfaces\NumericTypeInterface;
15: use chippyash\Type\Number\Complex\ComplexType;
16: use chippyash\Type\Number\Rational\RationalType;
17:
18: /**
19: * Integer Type
20: */
21: class IntType extends AbstractType implements NumericTypeInterface
22: {
23:
24: /**
25: * Negates the number
26: *
27: * @return \chippyash\Type\Number\IntType Fluent Interface
28: */
29: public function negate()
30: {
31: $this->value *= -1;
32:
33: return $this;
34: }
35:
36: /**
37: * Return the number as a Complex number i.e. n+0i
38: *
39: * @return \chippyash\Type\Number\Complex\ComplexType
40: */
41: public function asComplex()
42: {
43: return new ComplexType(
44: new RationalType(clone $this, new static(1)),
45: new RationalType(new self(0), new static(1))
46: );
47: }
48:
49: /**
50: * Return number as Rational number.
51: * NB, numerator and denominator will be caste as IntTypes
52: *
53: * @return \chippyash\Type\Number\Rational\RationalType
54: */
55: public function asRational()
56: {
57: return new RationalType(clone $this, new static(1));
58: }
59:
60: /**
61: * Return number as an IntType number.
62: *
63: * @return \chippyash\Type\Number\IntType
64: */
65: public function asIntType()
66: {
67: return clone $this;
68: }
69:
70: /**
71: * Return number as a FloatType number.
72: *
73: * @return \chippyash\Type\Number\FloatType
74: */
75: public function asFloatType()
76: {
77: return new FloatType($this->value);
78: }
79:
80: /**
81: * Return the absolute value of the number
82: *
83: * @return \chippyash\Type\Number\IntType
84: */
85: public function abs()
86: {
87: return new static(abs($this->value));
88: }
89:
90: /**
91: * Return all factors of this number (sorted)
92: *
93: * @return array [factor,factor, ...]
94: */
95: public function factors()
96: {
97: $number = $this->value;
98: $limit = floor(sqrt(abs($number)));
99: $ret = array();
100: for ($x = 1; $x <= $limit; $x++) {
101: if ($number % $x == 0) {
102: $other = intval($number / $x);
103: $ret[$x] = $x;
104: $ret[$other] = $other;
105: }
106: }
107: ksort($ret);
108: return array_values($ret);
109: }
110:
111: /**
112: * Return all prime factors of this number
113: *
114: * Adapted from
115: * @link http://www.thatsgeeky.com/2011/03/prime-factoring-with-php/
116: *
117: * @return array [primeFactor => exponent,...]
118: */
119: public function primeFactors()
120: {
121: // max_n = 2^31-1 = 2147483647
122: $number = $this->value;
123: $divisor = 2;
124: $factors = array();
125: $dmax = floor(sqrt($number));
126: $sieve = array_fill(1, $dmax, 1);
127: do {
128: $rFlag = false;
129: while ($number % $divisor == 0) {
130: $factors[$divisor] = (isset($factors[$divisor]) ? $factors[$divisor] + 1 : 1);
131: $number /= $divisor;
132: $rFlag = true;
133: }
134: if ($rFlag) {
135: $dmax = floor(sqrt($number));
136: }
137: if ($number > 1) {
138: for ($i = $divisor; $i <= $dmax; $i += $divisor) {
139: $sieve[$i] = 0;
140: }
141: do {
142: $divisor ++;
143: } while ($divisor < $dmax && $sieve[$divisor] != 1 );
144: if ($divisor > $dmax) {
145: $factors[$number] = (isset($factors[$number]) ? $factors[$number] + 1 : 1);
146: }
147: }
148: } while ($number > 1 && $divisor <= $dmax);
149:
150: return $factors;
151: }
152:
153: /**
154: * Return correctly typed value for this type
155: *
156: * @param mixed $value
157: *
158: * @return mixed
159: * @codeCoverageIgnore
160: */
161: protected function typeOf($value)
162: {
163: return intval($value);
164: }
165: }
166: