Sign in to follow this  

base 256 (and other bases 10)

This topic is 3859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to store pixel info (RGB values) in a single integer and I'm a bit boggled by the notion of such a big base. My thinking is that I could represent a pixel as an integer thus: int_rep = R*256^2 + G*256^1 + B*256^0 And, while this makes sense to most of my brain, I'm having trouble thinking about how certain values in G, for instance, might be the same as lesser values of G with certain values of B added in...though I have yet to find an example of this. My current development medium is MatLAB (I know), which is why I haven't gone my usual route of bit-pushing or structure building, so I'm afraid those are not viable options. Furthermore, I'll need to compare RGB values between images with this here, so I need this int_rep to be a unique representation. My other idea, which is uglier but perhaps more viable, is this: int_rep = R*10^6 + G*10^3 + B*10^0 which isn't as "smart", but foots the bill and keeps the values seperate. Actually, that will make it easier to study by examination as well, so I think I'll go with that. =) However I would like it if someone could either help me comprehend the base 256 deal, or point me to a tutorial of some kind. Thank you kindly =)

Share this post


Link to post
Share on other sites
Values are stored in memory as a sequence of bytes.
|0|1|2|3|4|5|6|7|8....


When you store your rgb values as bytes, they are stored in memory something like this:
|r|g|b|....


Integers however, take up 2, 4, 8 or more consecutive bytes. So storing ints x and y into memory looks like this:

|0|1|2|3|4|5|6|7|8|9|...
| ..x.. | ..y.. | .....

or rgb:
|r g b ?|r g b ?| ....


The ? denotes undefined value which you won't be using.

Once you grasp that, you realize that this base 256 is just assembling an int (at least 4 bytes in size from values in range 0..255, or bytes.

Base 10 is useless, since it's not natural representation for computer (unless you're working on ENIAC).

data in memory is stored in base 2, but the smallest addressable unit is a byte (8 bits - base256).

Unfortunately, you'll need to look into how values are represented in memory and all related topics to understand why base256 not only works, but why the problems you mention cannot occur.

This is done much more efficiently using binary shift operations and bitmasking.

int color = ( r & 0xff ) | ( (g << 8) & 0xff00 ) | ( (b << 16) & 0xff0000);

r = ( color & 0xff);
g = ( color >> 8 ) & 0xff;
b = ( color >> 16 ) & 0xff;


This is the same, but you'll need to look into bitwise operations to understand why it works. The above concept is also optimal from computer perspective, since it maps into the most basic processor operations.

Base 10 representation doesn't allow this, and makes comparisons much more difficult. From base256 you can calculate the difference very efficiently.


Another way to look at it is in hex notation. There, each individual channel will be a value in 0..ff range.

So an int representation will be: 0xRRGGBB. Given 0xab10ff, you know that R = ab, G = 10 and B = ff.

It's obvious from this that different colors will always result in different value, and equal colors always in identical value.

Share this post


Link to post
Share on other sites
Because 256 is a power of 2, the binary layout of a dword-coded colour is actually already in base-256. Similarly, because 256 is a power of 16, the hex layout is also in base-256.

The only difference is conceptual. We think of 0xFF6674 being a six-digit hex value. But if you consider pairs of hex-digits as being primaries, you have your desired representation. So if 00 is zero, 01 is one, ..., FF is two-hundred and fifty-five (with individual digits 0 through F being illegal), then that hex code is actually a three-digit number, with each digit corresponding to a colour-channel.

For the same reasons, arithmetic works out fine too. The problems only kick in when you start using an incompatible radix. As I figure it, the only reason we avoid arithmetic on colour-codes is carrying. A good example would be adding two middle-greens (0x008000 + 0x008000) and ending up with dark-blue (0x010000). This is indicative of the inappropriateness of radix-coding, not of base-16. You'll have exactly the same problem with base-256 colours. Addition and subtraction are perfectly valid operations if you can guarantee that the components never leave their range (and carry), but we can rarely be sure of that. Multiplication, on the other hand, is a rather different kettle of fish, and shouldn't be attempted unless you are can guarantee the same condition and are careful in the formulation of the multiplicand.

The fact that the natural numbers form a total order is a coincidence. We have (arbitrarily) deemed blue to be more significant than green, and red less significant than both. For this reason, inequalities have no meaning in the given context. And in the same way that it is impossible to define a communistic total order* on vectors, we cannot use radix-coding in an inequality-friendly manner.

Admiral

* I think I made that term up. I simply mean 'a total order in which each component is equally significant'.

Share this post


Link to post
Share on other sites
I think you (both) have a mistaken notion of what numerical base is.

Base 10, the decimal system we are all so familiar with, has 10 independent digits, with numbers represented by combining those ten digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) in a positional notation. Base 2, binary, has 2 digits, 0 and 1. Base 8, octal, has 8 digits, 0, 1, 2, 3, 4, 5, 6, 7. Base 16, hexadecimal, has 16 digits: 0, 1, 2, 3, 4 ,5, 6, 7, 8, 9, A, B, C, D, E, F.

Obviously, base 256 would have 256 digits. Equally obviously, you're not working in base 256. And you don't want to; you'd need 256 distinct digits to represent values, which is unwieldy.

You probably want to work in binary, instead, or hexadecimal. Both of these are particularly common in computer programming because common system word sizes are very conveniently expressed in hex and binary (one hex digit represents four binary digits or bits, so an eight bit byte is represented in two digits - quite compact).

Assuming 8-bits per color component per RGBA pixel, the integer representation is

(R * 2560) + (G * 2561) + (B * 2562) + (A * 2563)

where the values of R, G, B and A themselves are in the range [0-255]. Again, this is convenient in hex notation because the positional offsets are automatic:

RRGGBBAA

where nn represents two hexadecimal digits. FF, the highest possible two-digit hex value, is 255 in decimal - perfect for your needs.

Keep in mind that base notations are just different ways of representing the same values. 11012 == 158 == 1310 == D16

Share this post


Link to post
Share on other sites

This topic is 3859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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