Description
Conversions/OctalToDecimal.php::decimalToOctal uses floating-point division for the quotient update, so the loop produces wrong output (spurious leading zeros and a near-infinite number of iterations) for essentially every input.
function decimalToOctal($decimalNumber)
{
...
$octalNumber = '';
while ($decimalNumber > 0) {
$octalNumber = ($decimalNumber % 8) . $octalNumber;
$decimalNumber /= 8; // BUG: float division, not integer division
}
return $octalNumber;
}
In PHP, / returns a float whenever the operands are not evenly divisible, while % casts its operands to int. So once $decimalNumber drops below 8 the quotient becomes a fraction that stays > 0 for a very long time, and each extra iteration prepends (int)fraction % 8 == 0, i.e. a spurious '0'.
Trace for decimalToOctal(8) (correct answer: "10"):
8 % 8 = 0 → "0"; 8 / 8 = 1 (int, evenly divisible)
1 % 8 = 1 → "10"; 1 / 8 = 0.125 (float)
0.125 > 0 is still true → (int)0.125 % 8 = 0 → "010"; 0.125 / 8 = 0.015625
- … keeps prepending
'0' until the float underflows to 0
So the result is "0…010" with a long run of leading zeros (and hundreds of wasted iterations), not "10". Every value that isn't reduced to exactly 0 by integer steps is affected.
Expected behavior
decimalToOctal(8) → "10", decimalToOctal(64) → "100", decimalToOctal(1) → "1".
Actual behavior
The quotient becomes fractional, the while ($decimalNumber > 0) loop over-runs, and the output gains spurious leading zeros (e.g. decimalToOctal(8) does not return "10").
Suggested fix
Use integer division for the quotient:
$decimalNumber = intdiv((int)$decimalNumber, 8);
(or $decimalNumber = (int)($decimalNumber / 8);). A test asserting decimalToOctal(8) === "10" and decimalToOctal(64) === "100" would guard this.
Description
Conversions/OctalToDecimal.php::decimalToOctaluses floating-point division for the quotient update, so the loop produces wrong output (spurious leading zeros and a near-infinite number of iterations) for essentially every input.In PHP,
/returns a float whenever the operands are not evenly divisible, while%casts its operands to int. So once$decimalNumberdrops below 8 the quotient becomes a fraction that stays> 0for a very long time, and each extra iteration prepends(int)fraction % 8 == 0, i.e. a spurious'0'.Trace for
decimalToOctal(8)(correct answer:"10"):8 % 8 = 0→"0";8 / 8 = 1(int, evenly divisible)1 % 8 = 1→"10";1 / 8 = 0.125(float)0.125 > 0is still true →(int)0.125 % 8 = 0→"010";0.125 / 8 = 0.015625'0'until the float underflows to0So the result is
"0…010"with a long run of leading zeros (and hundreds of wasted iterations), not"10". Every value that isn't reduced to exactly0by integer steps is affected.Expected behavior
decimalToOctal(8)→"10",decimalToOctal(64)→"100",decimalToOctal(1)→"1".Actual behavior
The quotient becomes fractional, the
while ($decimalNumber > 0)loop over-runs, and the output gains spurious leading zeros (e.g.decimalToOctal(8)does not return"10").Suggested fix
Use integer division for the quotient:
(or
$decimalNumber = (int)($decimalNumber / 8);). A test assertingdecimalToOctal(8) === "10"anddecimalToOctal(64) === "100"would guard this.