Пример #1
0
 /**
  * Process the EqualRounded operator.
  *
  * @return boolean|null A boolean with a value of true if the two expressions are numerically equal after rounding and false if they are not. If either sub-expression is NULL, the operator results in NULL.
  * @throws \qtism\runtime\expressions\operators\OperatorProcessingException
  */
 public function process()
 {
     $operands = $this->getOperands();
     if ($operands->containsNull()) {
         return null;
     }
     if ($operands->exclusivelySingle() === false) {
         $msg = "The EqualRounded operator only accepts operands with a single cardinality.";
         throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
     }
     if ($operands->exclusivelyNumeric() === false) {
         $msg = "The EqualRounded operator only accepts operands with an integer or float baseType.";
         throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_BASETYPE);
     }
     // delegate the rounding to the RoundTo operator.
     $expression = $this->getExpression();
     $roundingMode = $expression->getRoundingMode();
     $figures = $expression->getFigures();
     if (gettype($figures) === 'string') {
         // Variable reference to deal with.
         $state = $this->getState();
         $varName = Utils::sanitizeVariableRef($figures);
         $varValue = $state[$varName];
         if (is_null($varValue) === true) {
             $msg = "The variable with name '{$varName}' could not be resolved.";
             throw new OperatorProcessingException($msg, $this, OperatorProcessingException::NONEXISTENT_VARIABLE);
         } elseif (!$varValue instanceof Integer) {
             $msg = "The variable with name '{$varName}' is not an integer.";
             throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_VARIABLE_BASETYPE);
         }
         $figures = $varValue->getValue();
     }
     $rounded = new OperandsCollection();
     // will contain the rounded operands.
     foreach ($operands as $operand) {
         $baseType = RuntimeUtils::inferBaseType($operand);
         $subExpression = new BaseValue($baseType, $operand);
         $roundToExpression = new RoundTo(new ExpressionCollection(array($subExpression)), $figures, $roundingMode);
         $roundToProcessor = new RoundToProcessor($roundToExpression, new OperandsCollection(array($operand)));
         try {
             $rounded[] = $roundToProcessor->process();
         } catch (OperatorProcessingException $e) {
             $msg = "An error occured while rounding '{$operand}'.";
             throw new OperatorProcessingException($msg, $this, OperatorProcessingException::LOGIC_ERROR, $e);
         }
     }
     return new Boolean($rounded[0]->getValue() == $rounded[1]->getValue());
 }
Пример #2
0
    public function testInfinity()
    {
        $expr = $this->createComponentFromXml('
			<roundTo figures="0" roundingMode="decimalPlaces">
				<baseValue baseType="float">3.4</baseValue>
			</roundTo>
		');
        $operands = new OperandsCollection(array(new Float(INF)));
        $processor = new RoundToProcessor($expr, $operands);
        $result = $processor->process();
        $this->assertTrue(is_infinite($result->getValue()));
        $this->assertTrue(INF === $result->getValue());
        $processor->setOperands(new OperandsCollection(array(new Float(-INF))));
        $result = $processor->process();
        $this->assertTrue(is_infinite($result->getValue()));
        $this->assertTrue(-INF === $result->getValue());
    }