Prev: How to C++ exe without installing C++ Redistributable Package
Next: Which Visual Studio for 64 Bit Apps
From: nki00 on 30 May 2010 04:40 Hi: I'm trying to determine the total amount of physical RAM in the system and report it for a user. I use the following approach: MEMORYSTATUSEX msx; msx.dwLength = sizeof (msx); if(GlobalMemoryStatusEx(&msx)) { CString strSz; unsigned __int64 ulDiv = 1024 * 1024 * 1024; //Or should it be: 1000 * 1000 * 1000 double fV = (double)msx.ullTotalPhys / ulDiv; strSz.Format(_T("%.2f GB"), fV); } It seems to work in Windows XP, but in Vista and Windows 7 I get the following discrepancies: RAM reported in msx.ullTotalPhys = 4252442624 bytes RAM resulting in strSz = "3.96 GB" RAM reported in the properties for My Computer = "Memory (RAM): 4.00 GB" I understand that the difference is not that much, but still, where does that 0.04 GB go? Or should I divide it by 1000 instead of 1024 increments? FYI. I'm running this test from a program that does not have admin privileges. Maybe that is why the result is off?
From: Jackie on 30 May 2010 07:12 On 5/30/2010 10:40, nki00 wrote: > Hi: > > > I'm trying to determine the total amount of physical RAM in the system and > report it for a user. I use the following approach: > > MEMORYSTATUSEX msx; > msx.dwLength = sizeof (msx); > if(GlobalMemoryStatusEx(&msx)) > { > CString strSz; > unsigned __int64 ulDiv = 1024 * 1024 * 1024; //Or should it be: 1000 * > 1000 * 1000 > double fV = (double)msx.ullTotalPhys / ulDiv; > strSz.Format(_T("%.2f GB"), fV); > } > > It seems to work in Windows XP, but in Vista and Windows 7 I get the > following discrepancies: > > RAM reported in msx.ullTotalPhys = 4252442624 bytes > RAM resulting in strSz = "3.96 GB" > RAM reported in the properties for My Computer = "Memory (RAM): 4.00 GB" > > I understand that the difference is not that much, but still, where does > that 0.04 GB go? Or should I divide it by 1000 instead of 1024 increments? > > FYI. I'm running this test from a program that does not have admin > privileges. Maybe that is why the result is off? > > > You can use 1000 if you mean GB (gigabytes) or 1024 if you mean GiB (gibibytes). You should however in this case use 1024. It's kind of annoying when you don't really know which one to use. For example with a 2 TB HDD, the manufacturer uses 1000 when they say "2 TB". You might notice that you only have 1.953 "TB" in Windows, but 1024 is used here instead and it still says "TB". I am a little curious now as well why it shows less for you, since it seems to work fine here. I wrote the code from scratch though: ---------------------------------------- MEMORYSTATUSEX memStatus; memStatus.dwLength = sizeof(memStatus); if (GlobalMemoryStatusEx(&memStatus)) { long double totalPhysGiB = memStatus.ullTotalPhys / pow(2.0, 30.0); long double totalPhysGB = memStatus.ullTotalPhys / pow(10.0, 9.0); _tprintf( _T("Total physical memory:\n") _T("%.2f: GiB\n") _T("%.2f: GB\n"), totalPhysGiB, totalPhysGB); } ---------------------------------------- Output: ---------------------------------------- Total physical memory: 4.00: GiB 4.29: GB ----------------------------------------
From: nki00 on 30 May 2010 14:56 Thanks. I modified your code just a little bit and ran it on XP and Vista: MEMORYSTATUSEX memStatus; memStatus.dwLength = sizeof(memStatus); if (GlobalMemoryStatusEx(&memStatus)) { long double totalPhysGiB = memStatus.ullTotalPhys / pow(2.0, 30.0); long double totalPhysGB = memStatus.ullTotalPhys / pow(10.0, 9.0); _tprintf( _T("Total physical memory:\n") _T("%I64d: Bytes\n") _T("%.2f: GiB\n") _T("%.2f: GB\n"), memStatus.ullTotalPhys, totalPhysGiB, totalPhysGB); } The output: ======================= WINDOWS XP Total physical memory: 2683285504: Bytes 2.50: GiB 2.68: GB In My Computer: 2.50 GB of RAM <---- CORREST! ======================= WINDOWS VISTA Total physical memory: 4252442624: Bytes 3.96: GiB 4.25: GB In My Computer: Memory (RAM): 4.00 GB <--- DOESN'T MATCH!!! ======================= Windows 7 has the same problem. Are they rounding it up, or what???? Maybe they use a different API there? Also, on the side note -- I don't think there's any difference between 'long' and 'long double', is there? At least I can't see any in the 32-bit machine code in my MS Visual Studio 2002.
From: Jackie on 30 May 2010 15:26 On 5/30/2010 20:56, nki00 wrote: > Are they rounding it up, or what???? Maybe they use a different API there? > Hmm. I am not competent enough to give a good answer that but I think that's a bit strange. You can also get the same value you see in "My Computer" via WMI. I have done this in C# but I need to have a look on how to do it in C++. Here's a WMI reference: http://msdn.microsoft.com/en-us/library/aa394572(VS.85).aspx WMI Classes > Win32 Classes > Computer System Hardware Classes > Win32_PhysicalMemory Class Capacity: "Total capacity of the physical memory�in bytes" Seems like you need to get Capacity from Win32_PhysicalMemory. > > Also, on the side note -- I don't think there's any difference between > 'long' and 'long double', is there? At least I can't see any in the 32-bit > machine code in my MS Visual Studio 2002. > > "double" is not the same as "long". "double" is a 64-bit floating-point type while "long" is a 32-bit integral type. I had a look here just now.. It is Microsoft-specific: http://msdn.microsoft.com/en-us/library/cc953fe1(VS.80).aspx Says "Type long double is a floating type that is equal to type double". I think you should just use "double" instead. Somehow I must have imagined that I got a warning while using "double" instead of "long double".
From: Jackie on 30 May 2010 17:19
Phew... Finally got around getting the total physical memory capacity via WMI. The code a bit long. I would usually break lines up when they get long, but I tried not to do it this time because there's a *lot* of uninteresting code here. Here it is: http://pastebin.com/u7fCZKd8 It will expire in a month. I followed the steps in this article (Getting WMI Data from the Local Computer): http://msdn.microsoft.com/en-us/library/aa390423(v=VS.85).aspx I added my previous code to display the information (unfortunately not your changes) and this is the output: ---------------------------------------- Total physical memory: 4.00: GiB 4.29: GB ---------------------------------------- If that doesn't work, I really have no idea how to solve that problem with my level of knowledge. I don't like the idea of rounding the number because I would assume that the value *should* be exact from the beginning. |