<?php


/**
 * Клас 'core_Math' ['math'] - Математически функции
 *
 *
 * @category  ef
 * @package   core
 *
 * @author    Milen Georgiev <milen@download.bg>
 * @copyright 2006 - 2014 Experta OOD
 * @license   GPL 3
 *
 * @since     v 0.1
 * @link
 */
class core_Math
{
    /**
     * "Интелигентно" закръгляне, което гарантира минимален брой
     * (зададен чрез конфигурация) знаци след закръглянето
     *
     * @param float $number            число, което подлежи на закръгляне
     * @param int   $fractionalLen     текуща максимална дробна част
     * @param int   $significantDigits минимален брой значещи цифри след закръглянето
     *
     * @return float|string закръглено число
     */
    public static function roundNumber($number, &$fractionalLen = 0, $significantDigits = null)
    {
        if (!$fractionalLen) {
            $fractionalLen = 0;
        }
        
        if ($significantDigits === null) {
            // Вземаме конфигурацията на пакета ef
            $significantDigits = core_Setup::get('EF_ROUND_SIGNIFICANT_DIGITS', true);
        }
        
        $r = 0;
        if (round($number, 10)) {
            $r = log10(abs($number));
        }

        // Плаваща, лимитирана от долу прецизност
        $precision = max($fractionalLen, floor($significantDigits - $r));
        
        // Закръгляваме
        $number = round($number, $precision);
        
        // Дължината на дробната част
        $thisFractionalLen = strlen(substr(strrchr($number, '.'), 1));
        
        if ($thisFractionalLen > $fractionalLen) {
            
            // Записваме новата по-голяма част
            $fractionalLen = $thisFractionalLen;
        } elseif ($thisFractionalLen < $fractionalLen) {
            
            // Падваме с 0-ли отдясно
            if (floor($number) != $number) {
                $number = str_pad($number, $fractionalLen, '0', STR_PAD_RIGHT);
            }
        }
        
        return $number;
    }
    
    
    /**
     * Функция намираща остатъка на делението на две реални числа
     *
     * @param float $x
     * @param float $y
     *
     * @return float $r
     */
    public static function fmod($x, $y)
    {
        $x = (double) $x;
        $y = (double) $y;
        expect($y != 0, 'Опит за деление на нула');
        
        $r = $x - floor($x / $y) * $y;
        
        return $r;
    }
    
    
    /**
     * Сравнява колко процента е разликата между две суми
     * 
     * @param double $amount1
     * @param double $amount2
     * 
     * @return double $diffInPercent
     */
    public static function diffInPercent($amount1, $amount2)
    {
        $diffInPercent = core_Math::roundNumber(1 - number_format($amount1, 8, '.', '') / number_format($amount2, 8, '.', '')) * 100;
        
        return $diffInPercent;
    }
}
