Page 1 of 1

Bytes conversion

Posted: Tue Mar 12, 2013 11:38 pm
by Thunder93
Hi.

I was trying out this bytes conversion code that was posted over the PB forum.
I can't seem to figure out how to make it behave in the manner detailed in the code. Hope someone can figure this out.

Code: Select all

Procedure.s bytecalc(byte.q, NbDecimals.l=0) 
   Protected unit.b = Round(Log(byte)/Log(1024), 0)
   ProcedureReturn StrD(byte/Pow(1024, unit), NbDecimals*(unit & 1))+" "+StringField("Byte,KB,MB,GB,TB,PB,EB", unit+1, ",")
EndProcedure 

Debug bytecalc(50)
Debug bytecalc(1024) + " <---- 1,024bytes = 1KB"
Debug bytecalc(1536) + " <---- 1,536bytes = 1.50KB instead of the shown 2KB result"
Debug bytecalc(2047) + " <---- 2,047bytes = 1.99KB instead of the shown 2KB result"
Debug bytecalc(2048) + " <---- 2,048bytes = 2KB <----This is 2KB"
Debug bytecalc(1048576 ) + " <---- 1,048,576bytes  = 1MB"
Debug bytecalc(1073741824) + " <---- 1,073,741,824bytes = 1GB instead of the shown 1024MB result"
Debug bytecalc(1099511627776) + " <---- 1,099,511,627,776bytes = 1TB"
Debug bytecalc(1125899906842624) + " <---- 1,125,899,906,842,624bytes = 1PB"

Re: Bytes conversion

Posted: Wed Mar 13, 2013 12:51 am
by idle

Code: Select all

Procedure.s bytecalc(byte.q, NbDecimals.l=0) 
   Protected output.s,*chr.Character 
   Protected unit.b = Round(Log(byte)/Log(1024), 0)
   output.s =   StrD(byte/Pow(1024, unit), 15)
    pos = FindString(output,".")
      *chr = @output + pos  
      If *chr\c <> '0' 
         output = Left(output,pos+2) + StringField("Bytes,KB,MB,GB,TB,PB,EB", unit+1, ",") 
      Else 
         output = Left(output,pos-1) + StringField("Bytes,KB,MB,GB,TB,PB,EB", unit+1, ",") 
      EndIf    
   ProcedureReturn output 
EndProcedure 

Debug bytecalc(50)
Debug bytecalc(1024) + " <---- 1,024bytes = 1KB"
Debug bytecalc(1536) + " <---- 1,536bytes = 1.53KB instead of the shown 2KB result"
Debug bytecalc(2047) + " <---- 2,047bytes = 1.99KB instead of the shown 2KB result"
Debug bytecalc(2048) + " <---- 2,048bytes = 2KB <----This is 2KB"
Debug bytecalc(1048576 ) + " <---- 1,048,576bytes  = 1MB"
Debug bytecalc(1073741824) + " <---- 1,073,741,824bytes = 1GB instead of the shown 1024MB result"
Debug bytecalc(1099511627776) + " <---- 1,099,511,627,776bytes = 1TB"
Debug bytecalc(1125899906842624) + " <---- 1,125,899,906,842,624bytes = 1PB"

Re: Bytes conversion

Posted: Wed Mar 13, 2013 1:01 am
by Thunder93
Wonderful work idle! :mrgreen:

Why is that GB showing 1024MB w/PB v5.11beta2 x86? that's odd

50Bytes
1KB <---- 1,024bytes = 1KB
1.50KB <---- 1,536bytes = 1.50KB
1.99KB <---- 2,047bytes = 1.99KB
2KB <---- 2,048bytes = 2KB
1MB <---- 1,048,576bytes = 1MB
1024MB <---- 1,073,741,824bytes = 1GB instead of the shown 1024MB result
1TB <---- 1,099,511,627,776bytes = 1TB
1PB <---- 1,125,899,906,842,624bytes = 1PB

Re: Bytes conversion

Posted: Wed Mar 13, 2013 2:01 am
by cxAlex
If you change line 3 from

Code: Select all

Protected unit.b = Round(Log(byte)/Log(1024), 0)
to

Code: Select all

Protected unit.b = Round(Log(byte)/Log(1024), #PB_Round_Nearest)
the 1 GB is shown correct.

Re: Bytes conversion

Posted: Wed Mar 13, 2013 2:27 am
by Thunder93
Thanks cxAlex!

Shouldn't think that this change would be necessary. Only an issue on the x86 versions of PB.

Re: Bytes conversion

Posted: Wed Mar 13, 2013 5:04 am
by Thunder93
Wait a minute! I didn't notice at the time, but my Bytes readings are messed up with the use of #PB_Round_Nearest. I have to leave that off :x
cxAlex wrote:If you change line 3 from

Code: Select all

Protected unit.b = Round(Log(byte)/Log(1024), 0)
to

Code: Select all

Protected unit.b = Round(Log(byte)/Log(1024), #PB_Round_Nearest)
the 1 GB is shown correct.

Re: Bytes conversion

Posted: Wed Mar 13, 2013 5:33 am
by idle
try this then

Code: Select all

#ZKB = 1024
#ZMB = #ZKB * 1024 
#ZGB = #ZMB * 1024
#ZTB = #ZGB * 1024
#ZPB = #ZTB * 1024 
#ZEB = #ZPB * 1024 


Procedure.s bytecalc(byte.q, NbDecimals.i=2) 
   Protected output.s,*chr.Character,unit.s 
      
   If Byte < #ZKB 
      output = Str(byte)
      unit = "Bytes"
   ElseIf byte < #ZMB 
      output = StrD(byte/#ZKB,15)
      unit = "KB"
   ElseIf byte < #ZGB 
      output = StrD(byte/#ZMB,15)
      unit = "MB"   
   ElseIf byte < #ZTB
      output = StrD(byte/#zGB,15)
      unit = "GB"
   ElseIf byte < #ZPB  
      output = StrD(byte/#ZTB,15)
      unit = "TB" 
   ElseIf byte < #ZEB 
      output = StrD(byte/#ZPB,15)
      unit = "PB"
   Else 
      output = StrD(byte/#ZEB,15)
      unit = "EB"
   EndIf    
     
    pos = FindString(output,".")
      *chr = @output + pos  
      If *chr\c <> '0' 
         output = Left(output,pos+NbDecimals) + unit
      Else 
         output = Left(output,pos-1) + unit
      EndIf    
   ProcedureReturn output
EndProcedure 

Debug bytecalc(50)
Debug bytecalc(1024) + " <---- 1,024bytes = 1KB"
Debug bytecalc(1536) + " <---- 1,536bytes = 1.53KB instead of the shown 2KB result"
Debug bytecalc(2047) + " <---- 2,047bytes = 1.99KB instead of the shown 2KB result"
Debug bytecalc(2048) + " <---- 2,048bytes = 2KB <----This is 2KB"
Debug bytecalc(1048576 ) + " <---- 1,048,576bytes  = 1MB"
Debug bytecalc(1073741824) + " <---- 1,073,741,824bytes = 1GB instead of the shown 1024MB result"
Debug bytecalc(1099511627776) + " <---- 1,099,511,627,776bytes = 1TB"
Debug bytecalc(1125899906842624) + " <---- 1,125,899,906,842,624bytes = 1PB"


Re: Bytes conversion

Posted: Wed Mar 13, 2013 5:42 am
by Thunder93
Thanks idle.

I also fixed the previous one by adding a extra line of code before the final output = Left(output, line.

Code: Select all

If Unit = 2 And Left(output,pos-1) ="1024":unit+1:output="1":EndIf
:lol:

Re: Bytes conversion

Posted: Wed Mar 13, 2013 8:58 am
by Shield
Bear in mind that one kilobyte is actually considered 1'000 bytes and not 1'024 bytes anymore.
The same goes for MB, GB, etc. The units 2^X are called kibibyte (KiB), mebibyte (MiB), etc.

You might want to incorporate that into the procedure.

Re: Bytes conversion

Posted: Wed Mar 13, 2013 2:21 pm
by Thunder93
Kibibyte 'KiB' usage would be accurate. But Microsoft still uses kilobyte = 1024bytes for its filesizes. If you programming for Windows and returning file sizes for instance, no good changing and complicating things.

Anyways, Its interesting why between the two versions of PureBasic, it's not consistent in the way it rounds off :?: