Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

calculating and displaying big numbers problem 1

Status
Not open for further replies.

SalehKiswani

IS-IT--Management
Jul 16, 2011
60
Hello everybody,
I have a problem of calculating and displaying big numbers

this simple code will explain the idea:
!=================================================================
!-- Direct calculation--
stop(10239421*8*512) ! gives wrong answer (negative)
!-----------------------------------------
!--define n as Long--
n=10239421*8*512
stop(n) ! gives wrong answer (negative)
!-----------------------------------------
!--define n1 as Decimal--
n1=10239421*8*512
stop(n1) ! gives wrong answer (negative)
!-----------------------------------------
! I tried to do the operation in two steps

n1=10239421*8
n1=n1*512
stop(n1) ! gives correct answer
(which is not applicable all time)
!-----------------------------------------
I faced this problem when I tried to use DIRECTORY function to get a list of file, so the file sizes which is so big give a result of nigative value

Any notes is appreciated

 
Hi!

10239421 * 8 * 512 = 41,940,668,416


Max value in LONG (signed integer) = 2,147,483,647

Max value in ULONG (unsigned integer) = 4,294,967,295

Both LONG & ULONG are insufficient for storing the value.

What was the DECIMAL length you used? Ideally I would use DECIMAL(13,0). The following works fine since I have used variables for the values.

Code:
intRes1                      LONG
intRes2                      ULONG
decRes                       DECIMAL(13,0)
fltRes                       REAL

Var1                         ULONG(10239421)
Var2                         ULONG(8)
Var3                         ULONG(512)

  CODE
  
  intRes1 = Var1 * Var2 * Var3
  intRes2 = Var1 * Var2 * Var3
  decRes  = Var1 * Var2 * Var3
  fltRes  = Var1 * Var2 * Var3
  
  MESSAGE('LONG    = ' & intRes1 & |
          '|ULONG  = ' & intRes2 & |
          '|DECIMAL = ' & decRes & |
          '|REAL    = ' & fltRes, 'Results')
          
  RETURN

Regards
 
Hi!

Forgot to explain ::

There are two types of arithmetic used by the Clarion RTL, integer & decimal maths. By using LONGs or constant values, the RTL uses integer maths (which is faster than decimal maths) and hence the result gets truncated. By using ULONGs, you are forcing decimal maths and hence the values are correct.

Regards
 
Hi!

You can also force decimal maths in LONGs by using 1.0 as the first variable to be multiplied as shown below ::

Code:
intRes1                      LONG
intRes2                      ULONG
decRes                       DECIMAL(13,0)
fltRes                       REAL

Var1                         LONG(10239421)
Var2                         LONG(8)
Var3                         LONG(512)

  CODE
  
  intRes1 = 1.0 * Var1 * Var2 * Var3
  intRes2 = 1.0 * Var1 * Var2 * Var3
  decRes  = 1.0 * Var1 * Var2 * Var3
  fltRes  = 1.0 * Var1 * Var2 * Var3
  
  MESSAGE('LONG    = ' & intRes1 & |
          '|ULONG  = ' & intRes2 & |
          '|DECIMAL = ' & decRes & |
          '|REAL    = ' & fltRes, 'Results')
          
  RETURN

Regards


 
Thank you ShankarJ,your expaination was suffcient to solve my problem


Lots of thanks

Regards
 
Hi ,
I did modified my programs which facing this problem and it is fine , but still I cant get the correct size of files exceeding the limit of LONG type (2,147,483,647)
Iam using the DIRECTORY function to get the files sizes but the big files size come in minus with a wrong figure.
I tried to modify the FIL:Size from Long to Decimal(20) in EQUATES.CLW but it didnt work.
 
Hi!

You cannot change it to DECIMAL(20) as a decimal(20) uses 11 bytes of storage as compared to a LONG which uses 4 bytes of storage. You can try changing it to a ULONG which will help you with files of sizes up to 4GB but beyond that you need to use the Windows API to find the file size.

What version of clarion do you use?

Regards
 
Hi!

If you have CWUTIL.inc & CWUTIL.clw in the <ClarionHome>\LIBSRC folder, make the following the changes ::

CWUTIL.inc (within the MODULE('cwutil.clw') structure (after GetFileDate definition))
----------
Code:
    GetFileSize( STRING iFile ),REAL

CWUTIL.clw (after GetFileDate procedure)
----------
Code:
!-----------------------------------------------------------------------------!
!GetFileSize
! Get the system File Size for the specified file.
!-----------------------------------------------------------------------------!
GetFileSize        PROCEDURE (STRING FileName)

hFindHandle        LONG,AUTO
gFileFind          GROUP( WIN32_FIND_DATA ),AUTO.
szFindFile         CSTRING(FILE:MaxFileName),AUTO
fFileSize          REAL

  CODE
  hFindHandle = 0
  fFileSize   = -1
  szFindFile  = CLIP (FileName)
  CLEAR (gFileFind)

  hFindHandle = FindFirstFile( szFindFile, gFileFind )
  IF hFindHandle = INVALID_LONG_VALUE OR hFindHandle <= 0
     RETURN fFileSize
  END

  FindClose (hFindHandle)
  
  fFileSize = (gFileFind.nFileSizeHigh * 4294967296) + gFileFind.nFileSizeLow

  RETURN fFileSize

Usage
-----
Code:
After a DIRECTORY() call, loop through the queue for files with a NEGATIVE size and call GetFileSize() as shown below ::

FilesQ                       QUEUE(FILE:Queue),PRE(FIL)
BigFileSize                    REAL
                             END

  CODE
  
  DIRECTORY(FilesQ, 'D:\Virtual Machines\ShankHome_XP\*.VMDK', FILE:LongName+FILE:KeepDir)
  
  LOOP F# = 1 TO RECORDS(FilesQ)
     GET(FilesQ, F#)
  
     IF FIL:Size < 0
        FIL:BigFileSize = GetFileSize('D:\Virtual Machines\ShankHome_XP\' & CLIP(FIL:Name))
        
        MESSAGE(CLIP(FIL:Name) & ' - File Size Changed from ' & FIL:Size & ' to ' & FIL:BigFileSize)
     END
  END
  
  RETURN

Regards
 
Hi ShankarJ
You are great .. everything is running fine
thank you

 
Hi everybody
I have one last problem in this topic
Iam trying to get the total disk space and free disk space for a drive using GetDiskFreeSpace API function.
for big drives I still have negative value and the rest is ok.

Thank you in advance
 
Thank you ShankarJ , DriveInfo is what I was looking for
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top