dcsimg
Results 1 to 5 of 5

Thread: Division causes overflow

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jul 2017
    Posts
    126

    Question Division causes overflow

    Hello!

    I have the following function to return the size of a file to me.

    Optionally, I want to have MB returned instead of KB.

    The first thing that I stumbled over was a file length > 2 GB.

    To work around this, I found the following hack: lRet = 2147483648# + (2147483648# - Abs(lRet))

    However, when I then divide this value (for example: 2438086656) by 1000000, I get an overflow exception.

    Can anybody tell me what I'm doing wrong here?

    Thank you!

    Code:
    Public Function FileLength(ByVal uPath As String, ByVal uMBInsteadOfByte As Boolean, ByVal uCaller As String) As Currency
    On Error GoTo ErrHandler
    
        Debug.Print "Getting filelen from " & uPath
        Debug.Assert modIO.FileExists(uPath)
    
        Dim ret As Currency 'We could have used Long here, but if ret < 0, then we need to add a huge number 
        ret = VBA.FileLen(uPath)
    
        If ret < 0 Then
            'bigger than 2 gb
           ret = 2147483648# + (2147483648# - Abs(ret)) 'Not sure what I'm doing here, I copied it from the internet
        End If
        
        Debug.Assert ret > 0
    
        If uMBInsteadOfByte Then
            ret = (ret \ 1000000) 'this causes an overflow exception. I don't see why. 
        End If
    
        FileLength = ret
    
    Exit Function
    ErrHandler:
    Debug.Print Err.Description
    Call WriteLog("#FileLength: " & Err.Description & ", err.number: " & Err.Number & ", Params: '" & uPath & "', caller: " & uCaller)
    On Error GoTo -1
    Debug.Assert False
    End Function

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,005

    Re: Division causes overflow

    The reason for the error is that integer division is used (\). Use (/) instead
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,972

    Re: Division causes overflow

    The FileLen() function doesn't handle huge files.

    Assuming there is really any need for this at all, I'd probably choose something like this:

    Code:
    Option Explicit
    
    Private Const GENERIC_READ As Long = &H80000000
    Private Const OPEN_ALWAYS = 4
    
    Public Enum SHARE_MODES
        FILE_SHARE_EXCLUSIVE = 0
        FILE_SHARE_READ = 1
        FILE_SHARE_WRITE = 2
        FILE_SHARE_DELETE = 4
        FILE_SHARE_ALL = FILE_SHARE_READ Or FILE_SHARE_WRITE Or FILE_SHARE_DELETE
    End Enum
    #If False Then
    Dim FILE_SHARE_EXCLUSIVE, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE, FILE_SHARE_ALL
    #End If
    
    Private Declare Function CloseHandle Lib "kernel32" ( _
        ByVal hObject As Long) As Long
    
    Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileW" ( _
        ByVal lpFileName As Long, _
        ByVal dwDesiredAccess As Long, _
        ByVal dwShareMode As SHARE_MODES, _
        ByVal lpSecurityAttributes As Long, _
        ByVal dwCreationDisposition As Long, _
        ByVal dwFlagsAndAttributes As Long, _
        ByVal hTemplateFile As Long) As Long
    
    Private Declare Function GetFileSizeEx Lib "kernel32" ( _
        ByVal hFile As Long, _
        ByRef curFileSize As Currency) As Long
    
    Private Sub Form_Load()
        Const TEST_FILE As String = "D:\VHDs\Vista w IE8\Vista SP1 x86 with IE8 2009-Apr.vhd"
        Dim hFile As Long
        Dim curFileSize As Currency
        Dim MBFileSize As Double
    
        hFile = CreateFile(StrPtr(TEST_FILE), _
                           GENERIC_READ, _
                           FILE_SHARE_ALL, _
                           0&, _
                           OPEN_ALWAYS, _
                           0&, _
                           0&)
        GetFileSizeEx hFile, curFileSize
        CloseHandle hFile
        MBFileSize = CDbl(curFileSize) / (1000000 / 10000)
    
        AutoRedraw = True
        ScaleLeft = -60
        ScaleTop = -60
        Cls
        Print TEST_FILE
        Print Format$(MBFileSize, "#,##0.000 \M\B")
    End Sub
    That uses a Currency as a stand-in for a 64-bit integer type. The result is converted to a Double (or you might use a Decimal Variant) and then corrected by 10000 before finally dividing by 1000000.

    Name:  sshot.png
Views: 88
Size:  1.9 KB

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,972

    Re: Division causes overflow

    You might also want to show more detail:

    Code:
    Print Format$(MBFileSize, "#,##0.000000 \M\B")

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Jul 2017
    Posts
    126

    Re: Division causes overflow

    Thanks both of you very much!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width