public function allocate(array $ratios)
    {
        if (count($ratios) === 0) {
            throw new \InvalidArgumentException('Cannot allocate to none, ratios cannot be an empty array');
        }

        $remainder = $this->amount;
        $results = [];
        $total = array_sum($ratios);

        if ($total <= 0) {
            throw new \InvalidArgumentException('Cannot allocate to none, sum of ratios must be greater than zero');
        }

        foreach ($ratios as $key => $ratio) {
            if ($ratio < 0) {
                throw new \InvalidArgumentException('Cannot allocate to none, ratio must be zero or positive');
            }
            $share = $this->getCalculator()->share($this->amount, $ratio, $total);
            $results[$key] = $this->newInstance($share);
            $remainder = $this->getCalculator()->subtract($remainder, $share);
        }

        if ($this->getCalculator()->compare($remainder, '0') === 0) {
            return $results;
        }

        $fractions = array_map(function ($ratio) use ($total) {
            $share = ($ratio / $total) * $this->amount;

            return $share - floor($share);
        }, $ratios);

        while ($this->getCalculator()->compare($remainder, '0') > 0) {
            $index = !empty($fractions) ? array_keys($fractions, max($fractions))[0] : 0;
            $results[$index]->amount = $this->getCalculator()->add($results[$index]->amount, '1');
            $remainder = $this->getCalculator()->subtract($remainder, '1');
            unset($fractions[$index]);
        }

        return $results;
    }