# Calculate diff within various ranges with holes

## Recommended Posts

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 ?

Julien

##### 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 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.
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 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 on other sites

Here is an example of jchd's approach.

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

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

If \$a < \$b Then
\$iMin = \$a
\$iMax = \$b
\$iResult = (\$b - \$a)
Else
\$iMin = \$b
\$iMax = \$a
\$iResult = (\$a - \$b)
EndIf
;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 on other sites

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
Next

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)
Next

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

\$delta = \$delta_full - \$hole_total

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

EndIf```

Edited by Aslak

## Create an account

Register a new account