Я столкнулся с интересной проблемой в моем коде "humanize_bytes ()". Этот цикл представляет проблему без всякой другой логики. Цикл должен быть остановлен, когда байты были усечены до «читабельного» уровня. Итерация продолжается до тех пор, пока окончательное значение не станет меньше 1024 (или не может быть указан байт).
Я начал изучать проблему, когда функция выдает «1024.0 P» для 1024 петабайт. Сначала я подумал, что случайно использую <= vs <, но при дальнейшей проверке я обнаружил, что происходит нечто более интересное. </p>
Этот код воспроизводит проблему. Я использую Perl 5.8.8.
use strict;
my $bytesize = 1024;
my $final = 1152921504606846720;
while (1) {
printf "bytesize %%d: %d %%f: %s %s final %%d: %19d %%f: %26f\n",
$bytesize,$bytesize,
(
$bytesize == $final ? '==' :
$bytesize > $final ? '>' :
$bytesize < $final ? '<' :
'<error>'
),
$final,$final;
last if $final < $bytesize;
$final /= $bytesize;
}
printf "final = bytesize d:%d f:%s %s final d:%d f:%f\n",
$bytesize,$bytesize,
(
$bytesize == $final ? '==' :
$bytesize > $final ? '>' :
$bytesize < $final ? '<' :
'<error>'
),
$final,$final;
Вывод, который я получаю:
bytesize %d: 1024 %f: 1024 < final %d: 1152921504606846720 %f: 1152921504606846720.000000
bytesize %d: 1024 %f: 1024 < final %d: 1125899906842623 %f: 1125899906842623.750000
bytesize %d: 1024 %f: 1024 < final %d: 1099511627775 %f: 1099511627775.999756
bytesize %d: 1024 %f: 1024 < final %d: 1073741823 %f: 1073741824.000000
bytesize %d: 1024 %f: 1024 < final %d: 1048575 %f: 1048576.000000
bytesize %d: 1024 %f: 1024 > final %d: 1023 %f: 1024.000000
final = bytesize d:1024 f:1024 > final d:1023 f:1024.000000
Здесь следует отметить, что конечное значение в десятичном виде - 1023, а в float - 1024. Как это может быть? И, очевидно, Perl использует десятичное представление.