Mod Operator (% in C#)
Basically, it returns the remainder of a division operation. For example, 13 Mod 4 = 1, because 13 / 4 = 3 w/ a remainder of 1. It's important to understand how the long value is created to understand why the function does what it does.
All the colors (Red, Green, Blue) are represented in the amounts of 0-255. For example, imagine the following value: R(8), G(3), B(1).
To understand why the function does what it does, let's look at a scenario where number values range from 0-9 (10 values) instead of 0-255 (256 values). How would you represent a single value that you can reverse engineer the values from? You can not simply add the values together (8 + 3 + 1 = 12) because it would be impossible to reverse engineer the original values. Instead, you must multiply values by the base. The base depends on the value range... in the example it is 10 because there are 10 values. The position is a zero-based index. Red's position is 0, Green's position is 1, Blue's position is 2.
Value * (Base^Position))
- Red(8) = (8 * 10^0) = 8 * 1 = 8
- Green(3) = (3 * 10^1) = 3 * 10 = 30
- Blue(1) = (1 * 10^2) = 1 * 100 = 100
8 + 30 + 100 = 138. And 138 can easily be reverse engineered (in fact, just by looking at it!). Mathematically reverse engineering it is done as so:
(CombinedValue / (Base^Position)) % Base = OriginalValue
.
- (138 / (10^0)) % 10 = (138 / 1) % 10 = 138 % 10 = 8 (Red)
- (138 / (10^1)) % 10 = (138 / 10) % 10 = 13 (decimal is truncated) % 10 = 3 (Green)
- (138 / (10^2)) % 10 = (138 / 100) %10 = 1 (decimal is truncated) % 10 = 1 (Blue)
The function does a few things:
- It uselessly does a bitwise operator
(lColor And &HFF00)
and (lColor And &HFF0000)
for some reason.
- It simplifies the mathematics. There is no point in dividing by 1 for red (256^0 = 1), and there is no point to using the modulo operator to retrieve Green because X % 256 = X for all X where X < 256. Also, 256^2 is equal to 65536.
- It uses the actual range that color values can be represented (0-255, 256 values).
You can actually use a simplified version of the function instead:
Private Function LongToRGB(lColor As Long) As String
Dim iRed As Long, iGreen As Long, iBlue As Long
iRed = lColor Mod 256
iGreen = (lColor / 256) Mod 256
iBlue = lColor / 65536
LongToRGB = Format$(iRed, "000") & ", " & Format$(iGreen, "000") & ", " & Format$(iBlue, "000")
End Function
Note that the last method is simply a string formatting function and has nothing to do with the mathematics.