1024バイトに KB
を使用する際に問題があります。接頭辞としてのキロは、一般的に1024ではないことを意味します。
1000 * 1000
、 1024 * 1024
、 1000 * 1024
MB >。
1.44 MBのフロッピーは、実際に 1.44 * 1000 * 1024
を保持します。
このうち唯一の実際の方法は、新しい KiB
(Kibibyte)を1024バイトを使用することです。
実装した方法にも 8.4Gi
を使用して 8.4 * 1024 * 1024
を使用できないという制限があります。この制限を取り除くために、私は Regexp :: Regexpから$ RE {num} {real} を使用しました。 \ d +
の代わりに共通を使用します。
他の答えのいくつかは、すべての可能性のある試合を書き出すことによって試合をハードワイヤします。エラーが発生しやすいことは言うまでもありません。この問題を回避するために、正規表現を生成するために%multiplier
のキーを使用しました。つまり、%乗数
から要素を追加または削除すると、手作業で正規表現を変更する必要はありません。
use strict;
use warnings;
use Regexp::Common;
my %multiplier;
my $multiplier_match;
{
# populate %multiplier
my %exponent = (
K => 1, # Kilo Kibi
M => 2, # Mega Mebi
G => 3, # Giga Gibi
T => 4, # Tera Tebi
P => 5, # Peta Pebi
E => 6, # Exa Exbi
Z => 7, # Zetta Zebi
Y => 8, # Yotta Yobi
);
while( my ($str,$exp) = each %exponent ){
@multiplier{ $str, "${str}B" } = (1000 ** $exp) x2; # K KB
@multiplier{ "${str}i", "${str}iB" } = (1024 ** $exp) x2; # Ki KiB
}
# %multiplier now holds 32 pairs (8*4)
# build $multiplier_match
local $" #" # fix broken highlighting
= '|';
my @keys = keys %multiplier;
$multiplier_match = qr(@keys);
}
sub remove_multiplier{
die unless @_ == 1;
local ($_) = @_;
# s/^($RE{num}{real})($multiplier_match)$/ $1 * $multiplier{$2} /e;
if( /^($RE{num}{real})($multiplier_match)$/ ){
return $1 * $multiplier{$2};
}
return $_;
}
1Kが1024を意味することが絶対必要な場合は、1行だけを変更する必要があります。
# @multiplier{ $str, "${str}B" } = (1000 ** $exp) x2; # K KB
@multiplier{ $str, "${str}B" } = (1024 ** $exp) x2; # K KB
Regexp :: Commonから $ RE {num} {real}
を使用したので、 5.3e1Ki
でも動作します。