Calculate diff within various ranges with holes

6 posts in this topic

I'll try to explain my problem the best I can :

I have several ranges of hexadecimal values, for example :  

Range1 = 0x000-0x8FFF

Range2 = 0xA000-0xAFFF

Range3 = 0xD010-0xD01F

Range4 = 0xE100-0xE2FF

I'm then given 2 values, lets say A & B (both are in some of these ranges, but I dont know in advance in which ones)... For example : 

A = 0x00F

B = 0xD015

I must calculate the difference between A & B,  but I must take the "holes" between ranges in account...     So simply doing A minus B won't work.

In that case, I should do : (B - min(Range3)) + Range2 + (max(Range1) - A)


But I never know in advance where A and B are located.   (I dont even know if A > B or B < A, which makes it even harder...)


Anyone with ideas or pre-made script to make my lifge easier ?


Thanks in advance :)



Share this post

Link to post
Share on other sites

I would start by converting the hex to decimal and then create a case statement to determine what range you are inside of. 

Some formulas for the math, and then convert back to hex.


Just one of those things where you get each piece working on its own first, and then piece them together at the end.

Share this post

Link to post
Share on other sites

Use X = Abs(a - b), the (row) span between A and B; then loop thru the holes within A and B and substract their span from X.

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

Thank you guys !

ViciousXUSMC : this is how I started it...   but I realized this made a lot of cases to manage

jchd : I guess this seems the simplest way.   I'll try that !    Thanks ;)


Share this post

Link to post
Share on other sites

Here is an example of jchd's approach.

    Range1 = 0x000-0x8FFF
    Range2 = 0xA000-0xAFFF
    Range3 = 0xD010-0xD01F
    Range4 = 0xE100-0xE2FF
    A = 0x00F
    B = 0xD015
    ans =  (B - min(Range3)) + Range2 + (max(Range1) - A)

Local $iMin, $iMax, $iResult
$a = 0x000F
$b = 0xD015

If $a < $b Then
    $iMin = $a
    $iMax = $b
    $iResult = ($b - $a)
    $iMin = $b
    $iMax = $a
    $iResult = ($a - $b)
;ConsoleWrite( "0x" & Hex($iResult, 4) & @CRLF)

; ------ Minus holes (spaces between the ranges). -------
If $iMin <= 0x8FFF And $iMax >= 0xA000 Then $iResult -= (0xA000 - 0x8FFF)                        ; 1st hole
;ConsoleWrite("1st hole 0x" & Hex((0xA000 - 0x8FFF),4) & @TAB & "0x" & Hex($iResult, 4) & @CRLF)

If $iMin <= 0xAFFF And $iMax >= 0xD010 Then $iResult -= (0xD010 - 0xAFFF)                        ; 2nd hole
;ConsoleWrite("2nd hole 0x" & Hex((0xD010 - 0xAFFF),4) & @TAB & "0x" & Hex($iResult, 4) & @CRLF)

If $iMin <= 0xD01F And $iMax >= 0xE100 Then $iResult -= (0xE100 - 0xD01F)                        ; 3rd hole
;ConsoleWrite("3rd hole 0x" & Hex((0xE100 - 0xD01F),4) & @TAB & "0x" & Hex($iResult, 4) & @CRLF)

If $iMax >= 0xE2FF Then $iResult -= ($iMax - 0xE2FF)                                             ; Max past last range
If $iMin >= 0xE2FF and $iMax >= 0xE2FF Then $iResult = 0                                         ; Min and Max past last range.
; ------ End of Minus holes -------

; Note: "$iResult -= (0xE100 - 0xD01F)" is the same as "$iResult = $iResult - (0xE100 - 0xD01F)"

MsgBox(0, "Result", "Answer: 0x" & Hex($iResult, 4) & @CRLF & @CRLF & _
        "For specific values of A = 0x00F and B = 0xD015 " & @CRLF & _
        "the check answer = (B - min(Range3)) + Range2 + (max(Range1) - A) = 0x" & _
        Hex(($b - 0xD010) + (0xAFFF - 0xA000) + (0x8FFF - $a), 4) & @CRLF)


Share this post

Link to post
Share on other sites

#6 ·  Posted (edited)

Thank you Malkey ;)

Your code would work if I always have the same quantity of ranges, but it can change...
I've done it this way (and it works quite well) :    


;values for examples
    $string_Ranges = "0x81000000-0x84FFFFFF; 0xA5000000-0xA7FFFFFF; 0xB4200000-0xB71FFFFF"
    $a = int("0xB6E995BF")
    $b = int("0x81040FFF")

    ;range string to array
    $a_ranges = StringSplit($string_Ranges,";")

    $h_qty = $a_ranges[0]-1  ;quantity of holes

    $position_a = 0
    $position_b = 0

    For $k=1 to $a_ranges[0]
        $r_min = StringMid(StringStripWS($a_ranges[$k],1+2),3,8)        ;get range min
        $r_max = StringMid(StringStripWS($a_ranges[$k],1+2),14,8)       ;get range max
        if $a >= int("0x"&$r_min) AND $a <= int("0x"&$r_max) then $position_a = $k      ;search if $a is in this range
        if $b >= int("0x"&$r_min) AND $b <= int("0x"&$r_max) then $position_b = $k  ;search if $b is in this range

    ConsoleWrite("Ranges : " & $string_Ranges & @CRLF)
    ConsoleWrite("$a (0x" & Hex($a) &") is in range : " & $position_a & @CRLF)
    ConsoleWrite("$b (0x" & Hex($b) &") is in range : " & $position_b & @CRLF)

    if $position_a = $position_b Then  ;if in same range -> cimple calculation
        $delta = $a - $b
        ConsoleWrite("Delta = " & $delta & @CRLF)

    Else ; if in different ranges --> substract holes

        $delta_full = $a - $b

        ConsoleWrite("Delta full = " & $delta_full & @CRLF)

        $hole_total = 0
        for $l = $position_b to $position_a-1
            $r_max = StringMid(StringStripWS($a_ranges[$l],1+2),14,8)       ;get range max
            $r_min = StringMid(StringStripWS($a_ranges[$l+1],1+2),3,8)      ;get range min of next range
            $hole_total += int("0x"&$r_min) - int("0x"&$r_max)

        ConsoleWrite("Hole total = " & $hole_total & @CRLF)

        $delta = $delta_full - $hole_total

        ConsoleWrite("Delta real = " & $delta & @CRLF)



Edited by Aslak

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