/** * Process the Gcd operator. * * @return integer The integer value equal in value to the greatest common divisor of the sub-expressions. If any of the sub-expressions is NULL, the result is NULL. * @throws \qtism\runtime\expressions\operators\OperatorProcessingException */ public function process() { $operands = $this->getOperands(); if ($operands->containsNull() === true) { return null; } if ($operands->anythingButRecord() === false) { $msg = "The Gcd operator only accepts operands with a cardinality of single, multiple or ordered."; throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY); } if ($operands->exclusivelyInteger() === false) { $msg = "The Gcd operator only accepts operands with an integer baseType."; throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_BASETYPE); } // Make a flat collection first. $flatCollection = new OperandsCollection(); $zeroCount = 0; $valueCount = 0; foreach ($operands as $operand) { if ($operand instanceof QtiScalar) { $valueCount++; if ($operand->getValue() !== 0) { $flatCollection[] = $operand; } else { $zeroCount++; } } elseif ($operand->contains(null)) { // Container with at least one null value inside. // -> If any of the sub-expressions is null or not numeric, returns null. return null; } else { // Container with no null values. foreach ($operand as $o) { $valueCount++; if ($o->getValue() !== 0) { $flatCollection[] = $o; } else { $zeroCount++; } } } } if ($zeroCount === $valueCount) { // All arguments of gcd() are 0. return new QtiInteger(0); } else { $g = $flatCollection[0]; $loopLimit = count($flatCollection) - 1; $i = 0; while ($i < $loopLimit) { $g = new QtiInteger(Utils::gcd($g->getValue(), $flatCollection[$i + 1]->getValue())); $i++; } return $g; } }
/** * @dataProvider gcdProvider * * @param integer $a * @param integer $b * @param integer $expected */ public function testGcd($a, $b, $expected) { $result = OperatorsUtils::gcd($a, $b); $this->assertInternalType('integer', $result); $this->assertSame($expected, $result); }