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 ilMathBCMathAdapter
8 * @author Michael Jansen <mjansen@databay.de>
9 */
10class ilMathBCMathAdapter extends ilMathBaseAdapter
11{
12    /**
13     * ilMathBcMathAdapter constructor.
14     * @param int $scale
15     */
16    public function __construct($scale = 0)
17    {
18        bcscale($scale);
19    }
20
21    /**
22     * {@inheritdoc}
23     */
24    public function add($left_operand, $right_operand, $scale = null)
25    {
26        return bcadd($this->normalize($left_operand), $this->normalize($right_operand), $this->normalize($scale));
27    }
28
29    /**
30     * {@inheritdoc}
31     */
32    public function sub($left_operand, $right_operand, $scale = null)
33    {
34        return bcsub($this->normalize($left_operand), $this->normalize($right_operand), $this->normalize($scale));
35    }
36
37    /**
38     * {@inheritdoc}
39     */
40    public function mul($left_operand, $right_operand, $scale = null)
41    {
42        return bcmul($this->normalize($left_operand), $this->normalize($right_operand), $this->normalize($scale));
43    }
44
45    /**
46     * {@inheritdoc}
47     */
48    public function div($left_operand, $right_operand, $scale = null)
49    {
50        if ($right_operand == 0) {
51            require_once 'Services/Math/exceptions/class.ilMathDivisionByZeroException.php';
52            throw new ilMathDivisionByZeroException(sprintf("Division of %s by %s not possible!", $left_operand, $right_operand));
53        }
54
55        return bcdiv($this->normalize($left_operand), $this->normalize($right_operand), $this->normalize($scale));
56    }
57
58    /**
59     * {@inheritdoc}
60     */
61    public function mod($left_operand, $right_operand)
62    {
63        if ($right_operand == 0) {
64            require_once 'Services/Math/exceptions/class.ilMathDivisionByZeroException.php';
65            throw new ilMathDivisionByZeroException(sprintf("Division of %s by %s not possible!", $left_operand, $right_operand));
66        }
67
68        return bcmod($this->normalize($left_operand), $this->normalize($right_operand));
69    }
70
71    /**
72     * {@inheritdoc}
73     */
74    public function pow($left_operand, $right_operand, $scale = null)
75    {
76        $left_operand = $this->normalize($left_operand);
77        $right_operand = $this->normalize($right_operand);
78        $scale = $this->normalize($scale);
79
80        // bcpow() only supports exponents less than or equal to 2^31-1.
81        // Also, bcpow() does not support decimal numbers.
82        // If you have scale set to 0, then the exponent is converted to an integer; otherwise an error is generated.
83        $left_operand_dec = $this->exp2dec($left_operand);
84        $right_operand_dec = $this->exp2dec($right_operand);
85
86        // bcpow does NOT support decimal exponents
87        if (strpos($right_operand_dec, '.') === false) {
88            return bcpow($left_operand_dec, $right_operand_dec, $scale);
89        }
90
91        return $this->applyScale(pow($left_operand, $right_operand), $scale);
92    }
93
94    /**
95     * {@inheritdoc}
96     */
97    public function sqrt($operand, $scale = null)
98    {
99        return bcsqrt($operand, $scale);
100    }
101
102    /**
103     * {@inheritdoc}
104     */
105    public function comp($left_operand, $right_operand, $scale = null)
106    {
107        return bccomp($left_operand, $right_operand, $scale);
108    }
109}
110