protected function scaleReduce($value) { if (!is_null($this->scale_amount)) { $scaled = BC::parse("{$value} " . ($this->scale_inverse ? '/' : '*') . " {$this->scale_amount}", null, 18); } else { $lengths = $this->lengths()->get(); $lCount = $lengths->count(); if ($lCount == 0) { $scaled = 0; } else { $lSum = $lengths->sum('scale_amount'); $adjLoops = BC::div($value, $lCount, 0); $adjUnits = BC::modfrac($value, $lCount, 18); $adjRemains = BC::modfrac($adjUnits, 1, 18); $adjUnits = BC::add($adjUnits, $this->getEpochValue(), 0); $adjustment = BC::mul($adjLoops, $lSum, 18); for ($lNum = $this->getEpochValue(); BC::comp($lNum, $adjUnits) < 0; $lNum = BC::parse("({$lNum} + 1) % {$lCount}", null, 0)) { $adjustment = BC::add($adjustment, $lengths[$lNum]->scale_amount, 18); } $scaled = BC::parse("{$adjustment} + ({$adjRemains} * {lAmount})", ['lAmount' => $lengths[BC::parse("({$lNum} - 1 + {$lCount}) % {$lCount}", null, 0)]->scale_amount], 18); } } return $scaled; }