From: nki00 on
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
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
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
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
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.