Select Case not selecting case?

It’s been a very long day, so it’s likely I need to go home and have a beer instead of doing this, but I’d love to wrap up something I’ve been working on first.

I’ve got a method to format bytes into a more human-readable number. This seems like a perfect place for a Select Case statment, which I don’t use very often but would like to, because they’re so much cleaner than nested if/then statements in situations like this.

fileSize is an int64 that’s passed into the method. I’m testing on a file set that’s more than 5GB (fileSize = 5650440192)

[code]dim ext as string

select case fileSize
Case Is < 1024
ext = " Bytes"
Case Is < 1024 * 1024
fileSize = fileSize/1024
ext = " KB"
Case Is < 1024 * 1024 * 1024
fileSize = fileSize/1024/1024
ext = " MB"
Case Is < 1024 * 1024 * 1024 * 1024
fileSize = fileSize/1024/1024/1024
ext = " GB"
Case Is < 1024 * 1024 * 1024 * 1024 *1024
fileSize = fileSize/1024/1024/1024/1024
ext = " TB"
else
break
end select

return fileSize.ToText + ext
[/code]

It always breaks at the else statement, never satisfying any of the cases. Am I missing something obvious here? (likely, but I just can’t see it)

Thanks

32 or 64-bit compilation?

Uh yeah. Make filesize a UInt64. An Int64 would roll over.

Thanks - the project was set to 32bit though I thought I had set it to 64 when setting it up.

Now for that beer…

Try this:

[code] // Param fileSize As Int64
// Return: String // Size rounded shorter

Dim ext as string

Const kbVal As Int64 = 1024
Const mbVal As Int64 = kbVal * 1024
Const gbVal As Int64 = mbVal * 1024
Const tbVal As Int64 = gbVal * 1024
Const ptVal As Int64 = tbVal * 1024

Dim fileSizeDecs As Double = fileSize

Select Case fileSize
Case Is < kbVal
ext = “Bytes”
Case Is < mbVal
fileSizeDecs = fileSize / kbVal
ext = “KB”
Case Is < gbVal
fileSizeDecs = fileSize / mbVal
ext = “MB”
Case Is < tbVal
fileSizeDecs = fileSize / gbVal
ext = “GB”
Case Is < ptVal
fileSizeDecs = fileSize / tbVal
ext = “TB”
else
ext = “Overflow!”
End select

Return fileSizeDecs.ToText(Xojo.Core.Locale.Current, "#,##0.## ")+ext
[/code]

Xojo maybe isn’t promoting the internal math to the larger correct container and losing accuracy. Using int64 pre-calculated consts you probably will force 64 bit math instead of 32 bit. That’s what I suppose based on past errors, not sure if this is your case. Not tested, test please.

I just replaced my code with yours and the result is better - Mine was telling me the 5.26GB test file set was 5GB (which I figured was something I’d have to look into tomorrow). Yours is telling me it’s 5.26GB.

Plus yours is cleaner. I prefer it to my “1024 * 1024 * 1024 * 1024” mess.

Thanks!

Your code was truncating the math, I made mine floating point and exposed 2 decimals.

Smaller, no Select. Accept Petabytes. Made just for fun.

Private Function ApproximateBytesString(numBytes As UInt64) As String Dim MemUnit() As String = Array("Overflow","Bytes","KB","MB","GB","TB","PB") Dim unit As Integer = 0 Dim unitVal As Double = numBytes For i As Integer = 1 to 6 If unitVal < 1024.0 Then unit = i Exit End unitVal = unitVal / 1024.0 Next Return unitVal.ToText(Xojo.Core.Locale.Current, "#,##0.## ")+MemUnit(unit) End Function