Sign in to follow this  
Followers 0
rassillon

Negative number equals 0

10 posts in this topic

Hello All,

I searched but didn't find and answer. Possibly my search-foo is off.

 

I will try to explain this clearly.

Using WMI I query Win32_VideoController

I then grab the "AdapterRAM" property from the results.

I then math it to get size in MBs.

This worked fine until I found an adapter that WMI stored the RAM size as a (neg INT32) 2's compliment number.

So to convert I added 2^32 to the result and then mathed it to get the MBs

That works fine too.

Problem is that since I don't know if I am going to get a regular positive INT32 or a 2's compliment negative INT32, I figured I would just see if the value was (<0) less that zero and then math accordingly.

That failed.

So I thought maybe my dyslexia was playing with my <> symbols so I reversed it to check for (>0) greater than zero.

That failed.

Standard logic says that if a number is not greater than 0 and not less than 0 then it must be 0.

So I change my comparison to (=0)

That worked.... Say what.... Am I high?

-2147483648 equals 0 ????

So to sum it up.

Win32_VideoController > AdapterRAM

If the result is +INT32 all good

If the result is -INT32 it = 0

$WMI = ObjGet("winmgmts:\\.\root\cimv2")
$items = $WMI.ExecQuery("Select * from Win32_VideoController","WQL",48)
For  $item in $items
        ConsoleWrite( "AdapterRAM: " & $item.AdapterRAM & @CRLF)
    $video_memory_MB = $item.AdapterRAM
    ConsoleWrite(VarGetType($video_memory_MB) & @CRLF)
;This fails when $video_memory_MB is a 2's compliment number (negative INT32)
;        If $video_memory_MB < 0 Then $video_memory_MB = $video_memory_MB + 2^32
;This too fails when $video_memory_MB is a 2's compliment number (negative INT32)
;        If $video_memory_MB > 0 Then $video_memory_MB = $video_memory_MB + 2^32
;This works when $video_memory_MB is a 2's compliment number (negative INT32)
    If $video_memory_MB = 0 Then $video_memory_MB = $video_memory_MB + 2^32
;If it is not a 2's compliment this is all that is needed
    $video_memory_MB = ($video_memory_MB / 1024) / 1024
        ConsoleWrite($video_memory_MB & @crlf)
Next

If there is some detail that I am not aware of why equaling zero makes sense... Please let me know.

 

Thanks in advance!

NOTE: Not all video cards return a 2's compliment negative number so if you run it and don't get a negative number try it on a different machine. I don't know why some stored as regular numbers and why some are 2's compliment negative numbers.... unless it is because I see it mostly on non-integrated cards... but that is just anecdotal...

 

Share this post


Link to post
Share on other sites



Actually no... It outputs False....

But....if I comment out the If statement where it does the 2's complement conversion then I don't get a valid ram value.

Even thought the comparison doesn't equate to True and by all indication the code inside the If statement does not run.

This works properly but apparently doesn't run but gives me the correct output.

If $video_memory_MB = 0 Then
        ConsoleWrite("This Happened" & @CRLF)
        $video_memory_MB = $video_memory_MB + 2^32
    EndIf 

This apparently doesn't run either and the commented line shouldn't matter but this fails to give the correct output

If $video_memory_MB = 0 Then
        ConsoleWrite("This Happened" & @CRLF)
    ;   $video_memory_MB = $video_memory_MB + 2^32
    EndIf

This doesn't work either but shouldn't matter

;If $video_memory_MB = 0 Then
    ;   ConsoleWrite("This Happened" & @CRLF)
    ;   $video_memory_MB = $video_memory_MB + 2^32
    ;EndIf

This doesn't work 

If $video_memory_MB > 0 Then
        ConsoleWrite("This Happened" & @CRLF)
        $video_memory_MB = $video_memory_MB + 2^32
    EndIf

This doesn't work

If $video_memory_MB < 0 Then
        ConsoleWrite("This Happened" & @CRLF)
        $video_memory_MB = $video_memory_MB + 2^32
    EndIf

This does work

If $video_memory_MB = 0 Then
        ConsoleWrite("This Happened" & @CRLF)
        $video_memory_MB = $video_memory_MB + 2^32
    EndIf

And either way the number output after the IF statement still prints as negative.

I don't know what is going on but it is weird.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Do you use the latest AutoIt release and which OS do you test on?

I have no way to check the condition (my graphics adapter culminates at a whopping 256 Mb). Anyway what is the actual memory size returned for cards with 1Gb, with 2Gb and with 4Gb?

@trancexx,

Can it be that it's a UINT32 vs. INT32 or INT64 vs. INT32 issue?

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

The machine shows 2gb of dedicated video memory

Thanks jchd! 

I totally overlooked that I hadn't upgraded all my machines with the latest version 

This is what I started with

Environment(Language:0409  Keyboard:00000409  OS:WIN_7/Service Pack 1  CPU:X64 OS:X64)

@AutoitVersion = 3.3.8.1

I updated to 

@AutoitVersion = 3.3.10.2

Now the evaluation works as expected. the negative number evaluates to less than zero.

I still can't explain why having that "if" statement there and none of the commands apparently ran works and  if either the whole "if" statement was commented out or just the line doing the 2's compliment conversion (which doesn't run) made things not work. Why it didn't run or work with < or > but it didn't run but did work with =....

I am sure there is some sort of explanation but it is apparently working now as one would expect.

Thank you very much both jchd and AdmiralAlkex for your input.

Share this post


Link to post
Share on other sites

@trancexx,

Can it be that it's a UINT32 vs. INT32 or INT64 vs. INT32 issue?

Unsigned is treated as signed and that's the whole thing.

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Ha, OK.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

 

-2147483648 equals 0 ????

 

Hex(-2147483648) equals 0x80000000

Which is not an WMI error code, according to MSDN -- but it is the Same format.

- WMI Error Codes

http://msdn.microsoft.com/en-us/library/windows/desktop/aa394559(v=vs.85).aspx

Perhaps, it doesn't know what it is.

But, according to WMI_Query ...

---

Description: The AdapterRAM property indicates the memory size of the video adapter.

Example: 64000

Origin: Win32_VideoController

IsArray: False

IsLocal: True

CIMTYPE: uint32

MappingStrings: Win32Registry|HardwareInformation.MemorySize

read: True

Units: Bytes

---

So then, the return is supposed to be in bytes -- right?

And bytes Never return as a negative number, Except in your case.

Could you provide the Make and Model of your Video Adapter?


Make yourself sheep and the wolves will eat you - Benjamin Franklin

Share this post


Link to post
Share on other sites

If your return is -2147483648 and the return type is is specified as uint32 (as stated by ripdad), you must have placed it in an int32 instead of uint32. In an int32 the most significant bit is interpreted as a sign, where as in uint32 there is no sign (all values are positive).

If you instead place the return it in an int32 it would give you 2147483648 (lucky it only switches the sign, other values could give totally different values), you could then divide it by 1024^2 to get RAM in megabytes.

Share this post


Link to post
Share on other sites

Did you get this fixed and any source code for it?

 

I'm not smart enough to figure this out but i also created a topic long time ago. However i finally see m$ has published this.

https://support.microsoft.com/en-us/kb/2495801

 

Any halp guys?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0