Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Hex Values

Kenn Nilsson
AeonVox
Join date: 24 May 2005
Posts: 897
03-29-2007 08:59
I have to admit, I'm not a hex-value genius...so I'm wondering if I might be able to get some help in the area...

...I understand enough to know that I would be able to transfer 3, 3-digit values through a single integer using a hex-value...and that's exactly what I'm after.

Essentially...I'd like to be able to take

hex = a + b + c

and pass it to a second script that:

a = hex(x);
b = hex(y);
c = hex(z);

I know a 'vector' or CSV would work under a lot of circumstances, but I'm trying to pass these three values under the on-rez parameters of an object...where I have only the integer params to work with...

I understand somewhere along the line I need to do an x0 type thing...I dunno...help?

--------------------------------------

Second question...completely unrelated to the first...

Does anyone know if the 'get-time' functions have any order on which is fastest and least intensive? I mean...is llGetUnixTime() faster than llGetTimeofDay? Or the reverse? Or are they the same? (Personally, I love llGetUnixTime)
_____________________
--AeonVox--

Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms chasing ghosts, eating magic pills, and listening to repetitive, addictive, electronic music.
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
03-29-2007 09:17
Not sure 'hex' has anything to do with it..

It's untested - at work on my lunch break here - but something like this might work.
CODE

integer Vector2Integer (vector v, integer flags)
{
integer f = (flags & 0xFF) << 24;
integer x = ((integer)v.x) << 16;
integer y = ((integer)v.y) << 8;
integer z = ((integer)v.z);

return x + y + z + f;
}

vector Integer2Vector (integer i)
{
vector v;

v.x = (i >> 16) & 0xFF;
v.y = (i >> 8) & 0xFF;
v.z = i & 0xFF;

return v;
}

integer Integer2Flags (integer i)
{
return i >> 24;
}

edit: uh.. this might break if any part of the vector is over 128.. The basic idea is right though, I think. Downside is that the code above only gives you 1m resolution. Since XYZ are only 24 bits total and you can stuff 32 into an integer, I used the other bits to pass flags. You could lose the flags bits and maybe get .25m resolution by using 10 bits each for XYZ..

edit edit: and when I say that hex has nothing to do with it then use hex notation anyway, I'm not being a jerk. Not on purpose anyway. This...
CODE
    v.z = i & 0xFF; 

...is exactly the same as this...
CODE
    v.z = i & 255; 

Unless you're talking about stuffing numbers into strings, hex and decimal (and octal and binary and etc) are just ways to represent numbers. The compiler (should) generate the same code regardless of which notation you use.

edit edit edit: and.. last edit I hope.. these functions definitely only work if X, Y and Z are always in the range of 0-255. If you're trying to pass a euler or some big height value or a non-region position, they're not going to work so well.
[/edits]
From: Kenn Nilsson
Second question...completely unrelated to the first...

Does anyone know if the 'get-time' functions have any order on which is fastest and least intensive? I mean...is llGetUnixTime() faster than llGetTimeofDay? Or the reverse? Or are they the same? (Personally, I love llGetUnixTime)

/me guesses that both are cheap but that llGetUnixTime is a little faster. The cost of making the ll call is probably more than the cost of what either one are doing.
Kenn Nilsson
AeonVox
Join date: 24 May 2005
Posts: 897
03-29-2007 09:49
Looks great. I'll try it out right away.

I'm actually not passing vectors at all...I'm passing integers, I just need to pass three separate integers of varying length (say, 15, 0, 101) as a single integer. I figured hiding the separate values in a hex-type would be the best way to go.

No worries about the 0-255 range, I'll always be between 0 and 200, with probably 98% of numbers coming between 0 and 100.

Thanks for the help...I THINK I'm understanding how it's working :)
_____________________
--AeonVox--

Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms chasing ghosts, eating magic pills, and listening to repetitive, addictive, electronic music.
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
03-29-2007 10:13
Oh. Oops. Should have read you post more clearly.. Was thinking about passing vectors with the on_rez param last night and saw the word vector in your post.. :)

From: Kenn Nilsson
I just need to pass three separate integers of varying length (say, 15, 0, 101) as a single integer.

Be careful of the word 'length' there. It takes 7 bits to store the numbers 65-127. The 'length' of the number doesn't really matter - what matters is the number of bits it takes to store that number.. Any time you reach a power-of-two (2, 4, 8, 16, 32, 64, 128, 256, etc), it takes an extra bit to store the possible values between 0 and that number.

From: Kenn Nilsson
I figured hiding the separate values in a hex-type would be the best way to go.

Maybe I'm just being picky but hex isn't a type, it's a notation. Binary 11111111, octal 337, decimal 255 and hex FF are all the exact same number. They're just different ways to write human-readable stuff. Underneath, the processor just sees 8 bits of data.
Kenn Nilsson
AeonVox
Join date: 24 May 2005
Posts: 897
03-29-2007 10:28
Awesome...I'll stop using the word hex :)

You're helping me immensely with my understanding actually. I really appreciate it. My background does not include education with bits...which is where it is immediately apparent that I lack understanding.

The way I currently understand it, I am able to pass up to 3 integers with a value of less than 256 (so 0-255) with 24 bits of information. I then have 8 bits left available to me in the integer, which I can use for a flag-value of 0-255...yes?

It then appears that we're using the << and >> operators to place each value in its correct...hmmm...I'll butcher the correct way to say it...but 'bit-location'...for the transfer and pull it out afterwards?

Essentially...I'm passing 4 8-bit integers in one 32-bit integer.

If I wanted to pass...8 integers in one, I would be restricted to 4 bit integers, which would require me to stay below a value of...16?
_____________________
--AeonVox--

Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms chasing ghosts, eating magic pills, and listening to repetitive, addictive, electronic music.
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
03-29-2007 10:37
From: Kenn Nilsson
Awesome...I'll stop using the word hex :)

You're helping me immensely with my understanding actually. I really appreciate it. My background does not include education with bits...which is where it is immediately apparent that I lack understanding.

The way I currently understand it, I am able to pass up to 3 integers with a value of less than 256 (so 0-255) with 24 bits of information. I then have 8 bits left available to me in the integer, which I can use for a flag-value of 0-255...yes?

It then appears that we're using the << and >> operators to place each value in its correct...hmmm...I'll butcher the correct way to say it...but 'bit-location'...for the transfer and pull it out afterwards?

You may find it easier to understand if you think in terms of multiplication instead of bit shifting. So if you know that each integer is between 0 and 255, you can use x*256*256+y*256+z, which is mathematically identical. As a beginner, this may help get you off the ground and debugging.

I'm sure other folks will jump in and say that multiplication is much slower than bit shifting. That's true, but any decent compiler will catch this and optimize it. LSL may not be that smart. So once you feel you have a good grasp of things, consider switching to the shift operators, especially if this is being done a lot.
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
03-29-2007 10:40
From: Kenn Nilsson

If I wanted to pass...8 integers in one, I would be restricted to 4 bit integers, which would require me to stay below a value of...8?

Not 8, 0 to 15.
1 bit: 0..1
2 bits: 0..3
3 bits: 0..7
4 bits: 0..15
5 bits: 0..31
6 bits: 0..63
7 bits: 0..127
8 bits: 0..255

Oh, and be careful to make sure that everything really is an integer. Something like

12. << 8

is likely to fail, because the decimal point makes the 12 a float, not an integer (unless LSL doesn't allow shifting of floats - I haven't checked)
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
03-29-2007 10:53
No worries. I'm off lunch now but this beats work. :)

From: Kenn Nilsson
The way I currently understand it, I am able to pass up to 3 integers with a value of less than 256 (so 0-255) with 24 bits of information. I then have 8 bits left available to me in the integer, which I can use for a flag-value of 0-255...yes?

That's one way to do it. You get 32 bits and you can split that up any way you want. You could have four 8-bit values (like you say) or two 16-bit values or one 16-bit and two 8-bit values. Or you could have thirty two 1-bit values.

Below are some "number of bits = possible value range" numbers. Note that "bit" means "binary digit"...
1-bit = 0 - 1
2-bits = 0 - 3
3-bits = 0 - 7
4-bits = 0 - 15
5-bits = 0 - 31
6-bits = 0 - 63
7-bits = 0 - 127
8-bits = 0 - 255
9-bits = 0 - 511
10-bits = 0 - 1023
11-bits = 0 - 2047
12-bits = 0 - 4095
13-bits = 0 - 8191

Notice that the max value is ((2 to the power of the number of binary digits used) minus 1). Just like decimal where we can use the digits 0-9, the max number of values you can do with three digits is ((10 to the power of the three) minus 1). Or, 999 = ((10 to the power of 3) - 1). It might sound confusing but once you get it, you'll smack yourself on the forehead and laugh.

From: Kenn Nilsson
It then appears that we're using the << and >> operators to place each value in its correct...hmmm...I'll butcher the correct way to say it...but 'bit-location'...for the transfer and pull it out afterwards?

They're called left shift and right shift. Uh..

/me distracts Kenn with a wikipedia article and hopes Newgate or somebody has a good way to explain this stuff easily..
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
03-29-2007 10:58
From: Kenn Nilsson
No worries about the 0-255 range, I'll always be between 0 and 200, with probably 98% of numbers coming between 0 and 100.
If the values never exceed 255, then 8 bits, or 2 hex digits, for each will be plenty.

Meade's decoding code looks good, since a vector is the easiest way to return 3 numeric values from a single function call. Just cast the x/y/z components to ints afterward.

Encoding could be simplified to:

CODE

integer EncodeInt( integer i0, integer i1, integer i2 )
{
i0 = i0 & 0xFF;
i0 = i0 | ( ( i1 & 0xFF ) << 8 );
i0 = i0 | ( ( i2 & 0xFF ) << 16 );

return i0;
}

And if you're sure a value exceeding 255 would never be passed in, you can skip the first step and the "& 0xFF" of the next two. But this way, if a >255 value did get through, it wouldn't corrupt the next integer.
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
03-29-2007 11:00
From: Kidd Krasner
(unless LSL doesn't allow shifting of floats - I haven't checked)

It doesn't... I've tried.
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
03-29-2007 11:22
Er.. Just outta curiousity, what would you want 2.4 << 2 to return?
Kenn Nilsson
AeonVox
Join date: 24 May 2005
Posts: 897
03-29-2007 12:31
Wow...thanks for all the amazing help everyone. I've just gone through a couple of hours of lights flipping on all over in my head. Suddenly so much more makes so much sense.

I've also got things working great...so thank you, thank you, thank you.
_____________________
--AeonVox--

Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms chasing ghosts, eating magic pills, and listening to repetitive, addictive, electronic music.
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
03-29-2007 13:33
From: Meade Paravane
Er.. Just outta curiousity, what would you want 2.4 << 2 to return?
Well, if it worked, I'd expect 9.40395704865584E-39:

0100 0000 0001 1001 1001 1001 1001 1010 << 2 ==
0000 0000 0110 0110 0110 0110 0110 1000

But, I think the only time I tried doing this intentionally in LSL, I was attempting a direct bit-for-bit translation of a float to an int, but that didn't work because none of the other bitwise operators work on floats, either, so I had to do it the hard way.
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
03-29-2007 15:12
From: Meade Paravane
Er.. Just outta curiousity, what would you want 2.4 << 2 to return?

In the good old C and Bliss on PDP-11 days, I'd expect it to take the floating point representation of 2.4, shift it left two bits, thus returning something totally meaningless.

I don't recall whether K&R C would actually do this - there's not much point in memorizing what dumb programming practices do.
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
03-29-2007 16:08
From: Kidd Krasner
In the good old C and Bliss on PDP-11 days, I'd expect it to take the floating point representation of 2.4, shift it left two bits, thus returning something totally meaningless.
Yeah, that's what I did in my post above. :cool:
Sindy Tsure
Will script for shoes
Join date: 18 Sep 2006
Posts: 4,103
03-29-2007 18:23
Gotta be careful how you extract any number that you store in the high bit - LSL does arithmatic shifts and will copy the MSB when you shift right.

Doing this...
CODE
default
{
touch_start(integer total_number)
{
integer i = 1;

i = i << 31;
i = i >> 31;

llOwnerSay ((string)i);
}
}

...will say -1.
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
Someone Call?
03-29-2007 23:52
From: Meade Paravane
/me distracts Kenn with a wikipedia article and hopes Newgate or somebody has a good way to explain this stuff easily..



Nope I think you pretty much got it covered.
If you did want to start playing around with floats then you could always fall back onto B-Scaling.