@@ -65,8 +65,6 @@ pub const PIB: u64 = 1_125_899_906_842_624;
6565
6666static UNITS : & str = "KMGTPE" ;
6767static UNITS_SI : & str = "kMGTPE" ;
68- static LN_KB : f64 = 6.931471806 ; // ln 1024
69- static LN_KIB : f64 = 6.907755279 ; // ln 1000
7068
7169pub fn kb < V : Into < u64 > > ( size : V ) -> u64 {
7270 size. into ( ) * KB
@@ -181,7 +179,11 @@ impl ByteSize {
181179
182180pub fn to_string ( bytes : u64 , si_prefix : bool ) -> String {
183181 let unit = if si_prefix { KIB } else { KB } ;
184- let unit_base = if si_prefix { LN_KIB } else { LN_KB } ;
182+ let unit_sizes = if si_prefix {
183+ [ KIB , MIB , GIB , TIB , PIB ]
184+ } else {
185+ [ KB , MB , GB , TB , PB ]
186+ } ;
185187 let unit_prefix = if si_prefix {
186188 UNITS_SI . as_bytes ( )
187189 } else {
@@ -192,16 +194,20 @@ pub fn to_string(bytes: u64, si_prefix: bool) -> String {
192194 if bytes < unit {
193195 format ! ( "{} B" , bytes)
194196 } else {
195- let size = bytes as f64 ;
196- let exp = match ( size. ln ( ) / unit_base) as usize {
197- e if e == 0 => 1 ,
198- e => e,
199- } ;
197+ let mut ideal_size = unit_sizes[ 0 ] ;
198+ let mut ideal_prefix = unit_prefix[ 0 ] ;
199+ for ( & size, & prefix) in unit_sizes. iter ( ) . zip ( unit_prefix. iter ( ) ) {
200+ ideal_size = size;
201+ ideal_prefix = prefix;
202+ if size <= bytes && bytes / unit_sizes[ 0 ] < size {
203+ break ;
204+ }
205+ }
200206
201207 format ! (
202208 "{:.1} {}{}" ,
203- ( size / unit . pow ( exp as u32 ) as f64 ) ,
204- unit_prefix [ exp - 1 ] as char ,
209+ bytes as f64 / ideal_size as f64 ,
210+ ideal_prefix as char ,
205211 unit_suffix
206212 )
207213 }
0 commit comments