1<?php
2/* Copyright (c) 1998-2017 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once 'Services/Math/classes/class.ilMathBaseAdapter.php';
5
6/**
7 * Class ilMathPhpAdapter
8 * @author Michael Jansen <mjansen@databay.de>
9 */
10class ilMathPhpAdapter extends ilMathBaseAdapter
11{
12    /**
13     * {@inheritdoc}
14     */
15    public function add($left_operand, $right_operand, $scale = null)
16    {
17        $res = $this->normalize($left_operand) + $this->normalize($right_operand);
18
19        return $this->applyScale($res, $this->normalize($scale));
20    }
21
22    /**
23     * {@inheritdoc}
24     */
25    public function sub($left_operand, $right_operand, $scale = null)
26    {
27        $res = $this->normalize($left_operand) - $this->normalize($right_operand);
28
29        return $this->applyScale($res, $this->normalize($scale));
30    }
31
32    /**
33     * {@inheritdoc}
34     */
35    public function mul($left_operand, $right_operand, $scale = null)
36    {
37        try {
38            $res = $this->normalize($left_operand) * $this->normalize($right_operand);
39
40            $multiplication = $this->applyScale($res, $this->normalize($scale));
41        } catch (Throwable $e) {
42            if (strpos($e->getMessage(), 'A non-numeric value encountered') !== false) {
43                $multiplication = 0;
44            } else {
45                throw $e;
46            }
47        }
48
49        return $multiplication;
50    }
51
52    /**
53     * {@inheritdoc}
54     */
55    public function div($left_operand, $right_operand, $scale = null)
56    {
57        if ($right_operand == 0) {
58            require_once 'Services/Math/exceptions/class.ilMathDivisionByZeroException.php';
59            throw new ilMathDivisionByZeroException(sprintf("Division of %s by %s not possible!", $left_operand, $right_operand));
60        }
61
62        // This ensures the old PHP <= 7.0.x behaviour, see: #27785 / #26361
63        try {
64            $res = $this->normalize($left_operand) / $this->normalize($right_operand);
65
66            $division = $this->applyScale($res, $this->normalize($scale));
67        } catch (Throwable $e) {
68            if (strpos($e->getMessage(), 'A non-numeric value encountered') !== false) {
69                $division = 0;
70            } else {
71                throw $e;
72            }
73        }
74
75        return $division;
76    }
77
78    /**
79     * {@inheritdoc}
80     */
81    public function mod($left_operand, $right_operand)
82    {
83        if ($right_operand == 0) {
84            require_once 'Services/Math/exceptions/class.ilMathDivisionByZeroException.php';
85            throw new ilMathDivisionByZeroException(sprintf("Division of %s by %s not possible!", $left_operand, $right_operand));
86        }
87
88        $res = $this->normalize($left_operand) % $this->normalize($right_operand);
89
90        return $res;
91    }
92
93    /**
94     * {@inheritdoc}
95     */
96    public function pow($left_operand, $right_operand, $scale = null)
97    {
98        $res = pow($this->normalize($left_operand), $this->normalize($right_operand));
99
100        return $this->applyScale($res, $this->normalize($scale));
101    }
102
103    /**
104     * {@inheritdoc}
105     */
106    public function sqrt($operand, $scale = null)
107    {
108        $res = sqrt($this->normalize($operand));
109
110        return $this->applyScale($res, $this->normalize($scale));
111    }
112
113    /**
114     * {@inheritdoc}
115     */
116    public function comp($left_operand, $right_operand, $scale = null)
117    {
118        $left_operand = $this->normalize($left_operand);
119        $right_operand = $this->normalize($right_operand);
120        $scale = $this->normalize($scale);
121
122        if (is_numeric($scale)) {
123            $left_operand = $this->applyScale($left_operand, $scale);
124            $right_operand = $this->applyScale($right_operand, $scale);
125        }
126
127        if ($left_operand == $right_operand) {
128            return 0;
129        } elseif ($left_operand > $right_operand) {
130            return 1;
131        } else {
132            return -1;
133        }
134    }
135}
136