Difference between revisions of "Hex"
(→Demo: add the astonishing 0x123456789 example (saturates at min neg equal to max unsigned, rather than rolling over in two's complement like C often does)) |
m (<lsl> tag to <source>) |
||
(82 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
{{LSL Header}} | {{LSL Header}} | ||
__TOC__ | |||
<div id="box"> | <div id="box"> | ||
{{#vardefine:p_value_desc|value to be | {{#vardefine:p_value_desc|signed value to be expressed as negative or nonnegative hex}} | ||
== Function: [[string]] hex([[integer]] {{LSL Param|value}}); == | == Function: [[string]] hex([[integer]] {{LSL Param|value}}); == | ||
<div style="padding: 0.5em;"> | <div style="padding: 0.5em;"> | ||
Returns the hexadecimal nybbles of the signed integer | |||
Returns the hexadecimal nybbles of the signed integer value in order. Specifically returns the nybbles from most to least significant, starting with the first nonzero nybble, folding every nybble to lower case, and beginning with the nonnegative prefix "0x" or the negative prefix "-0x". | |||
Parameters: | Parameters: | ||
Line 11: | Line 15: | ||
|} | |} | ||
Note: Always begins any result of eight nybbles with one of the positive signed nybbles 1 2 3 4 5 6 7, never with a zero or unsigned nybble 0 8 9 A B C D E F, except for the boundary test case of the most negative integer "-0x80000000". | |||
</div> | |||
</div> | |||
</div></div> | |||
<div id="box"> | <div id="box"> | ||
== | |||
== Code == | |||
<div style="padding: 0.5em;"> | <div style="padding: 0.5em;"> | ||
string | The brief, clear, conventional code here implements this specification exactly. | ||
The [[Efficient Hex]] article presents an alternative approach: clever, small, and fast code to implement the same specification and related specifications, and also links to instruments that measure small and fast. | |||
<source lang="lsl2"> | |||
// http://wiki.secondlife.com/wiki/hex | |||
string XDIGITS = "0123456789abcdef"; // could be "0123456789ABCDEF" | |||
string | string hexes(integer bits) | ||
{ | { | ||
string nybbles = ""; | |||
string nybbles = | while (bits) | ||
{ | { | ||
integer lsn = bits & 0xF; // least significant nybble | |||
string nybble = llGetSubString(XDIGITS, lsn, lsn); | |||
nybbles = nybble + nybbles; | |||
bits = bits >> 4; // discard the least significant bits at right | |||
bits = bits & 0xfffFFFF; // discard the sign bits at left | |||
} | } | ||
return | return nybbles; | ||
} | } | ||
string hex(integer value) | string hex(integer value) | ||
{ | { | ||
if (value | if (value < 0) | ||
if (value | { | ||
return | return "-0x" + hexes(-value); | ||
} | |||
else if (value == 0) | |||
{ | |||
return "0x0"; // hexes(value) == "" when (value == 0) | |||
} | |||
else // if (0 < value) | |||
{ | |||
return "0x" + hexes(value); | |||
} | |||
} | } | ||
</source> | |||
</div> | |||
</div> | |||
<div id="box"> | |||
== Demo Results == | |||
<div style="padding: 0.5em;"> | |||
Running the demo should produce exactly these results: | |||
<pre> | |||
Hello | |||
0x0 == 0 | |||
0x400 == (0x00FEDC00 & -0x00FEDC00) | |||
0x40000000 == (1 << 30) | |||
-0x80000000 == 0x80000000 | |||
-0x123678a == 0xFEDC9876 | |||
-0x1 == -1 | |||
-0x1 == 0x123456789 | |||
OK | |||
Hello again | |||
0x7fffffff as base | |||
0x7fffffff by owner | |||
0x0 by group | |||
0x0 by anyone | |||
0x82000 by next owner | |||
aka 532480 | |||
OK | |||
</pre> | </pre> | ||
</div></div> | |||
</div> | |||
</div> | |||
<div id="box"> | <div id="box"> | ||
Line 54: | Line 101: | ||
== Demo == | == Demo == | ||
<div style="padding: 0.5em;"> | <div style="padding: 0.5em;"> | ||
To reproduce exactly the expected demo results above, run the demo code below. | |||
< | |||
We chose test cases that astonish people new to hex and test cases that astonish people new to LSL permission masks. | |||
You'll get the permission mask results we show if you create a New Script to run this demo in. If instead you try modifying some old script to run this demo, then you might have to edit its permission masks to get the demo results that we show here. | |||
<source lang="lsl2"> | |||
default | default | ||
{ | { | ||
Line 63: | Line 114: | ||
{ | { | ||
llOwnerSay("Hello"); | llOwnerSay("Hello"); | ||
llOwnerSay(hex(0)); | llOwnerSay(hex(0) + " == 0"); | ||
llOwnerSay(hex(0x00FEDC00 & -0x00FEDC00)); | llOwnerSay(hex(0x00FEDC00 & -0x00FEDC00) + " == (0x00FEDC00 & -0x00FEDC00)"); | ||
llOwnerSay(hex(1 << 30)); | llOwnerSay(hex(1 << 30) + " == (1 << 30)"); | ||
llOwnerSay(hex( | llOwnerSay(hex(0x80000000) + " == 0x80000000"); | ||
llOwnerSay(hex(0xFEDC9876)); | llOwnerSay(hex(0xFEDC9876) + " == 0xFEDC9876"); | ||
llOwnerSay(hex(-1)); | llOwnerSay(hex(-1) + " == -1"); | ||
llOwnerSay(hex(0x123456789)); | llOwnerSay(hex(0x123456789) + " == 0x123456789"); | ||
llOwnerSay("OK"); | llOwnerSay("OK"); | ||
llOwnerSay("Hello again"); | llOwnerSay("Hello again"); | ||
string item = llGetScriptName(); | string item = llGetScriptName(); | ||
llOwnerSay(hex(llGetInventoryPermMask(item, MASK_BASE))); | llOwnerSay(hex(llGetInventoryPermMask(item, MASK_BASE)) + " as base"); | ||
llOwnerSay(hex(llGetInventoryPermMask(item, MASK_OWNER))); | llOwnerSay(hex(llGetInventoryPermMask(item, MASK_OWNER)) + " by owner"); | ||
llOwnerSay(hex(llGetInventoryPermMask(item, MASK_GROUP))); | llOwnerSay(hex(llGetInventoryPermMask(item, MASK_GROUP)) + " by group"); | ||
llOwnerSay(hex(llGetInventoryPermMask(item, MASK_EVERYONE))); | llOwnerSay(hex(llGetInventoryPermMask(item, MASK_EVERYONE)) + " by anyone"); | ||
llOwnerSay(hex(llGetInventoryPermMask(item, MASK_NEXT))); | llOwnerSay(hex(llGetInventoryPermMask(item, MASK_NEXT)) + " by next owner"); | ||
llOwnerSay((string) llGetInventoryPermMask(item, MASK_NEXT)); | llOwnerSay("aka " + (string) llGetInventoryPermMask(item, MASK_NEXT)); | ||
llOwnerSay("OK"); | llOwnerSay("OK"); | ||
} | } | ||
} | } | ||
</ | </source> | ||
</div> | |||
</div> | |||
<div id="box"> | |||
== Specification == | |||
<div style="padding: 0.5em;"> | |||
We chose requirements that astonish people who usually write clever, small, or fast code by taking as precedent a specification from the far off world of people who usually write brief, clear, and conventional code. | |||
We require exactly the same results as the hex function of the popular Python scripting language. We thus reproduce how hex integer literals often appear in LSL script, conforming to such arbitrary and traditional AT&T C conventions as: | |||
# return lower case a b c d e f rather than upper case A B C D E F, | |||
# return a signed 31-bit result if negative, rather than an unsigned 32-bit result, | |||
# omit the leading zeroed nybbles, except return "0x0" rather than "0x" when the result is zero, | |||
# return a meaningless "0" before the "x", as LSL and C compilers require, | |||
# return the "x" on the left as in LSL and C, not the "h" on the right as in Assembly code, and | |||
# return the nybbles listed from most to least significant as in English, not listed from least to most significant as in Arabic. | |||
Brief doc for the Python hex function appears buried deep within http://docs.python.org/lib/built-in-funcs.html | |||
Disputes over the detailed specification of the Python hex function appear buried deep within http://www.python.org/dev/peps/pep-0237/ | |||
</div> | |||
</div> | |||
</ | |||
<div id="box"> | <div id="box"> | ||
== See Also == | == See Also == | ||
<div style="padding: 0.5em"> | <div style="padding: 0.5em;"> | ||
'''Articles''' | |||
* [[Efficient Hex]] | |||
'''Functions''' | '''Functions''' | ||
* [[llGetInventoryPermMask]] | * [[llGetInventoryPermMask]] | ||
* [[llGetObjectPermMask]] | * [[llGetObjectPermMask]] | ||
* [[ | * [[llIntegerToBase64]] | ||
* | |||
</div></div> | '''Wikipedia''' | ||
* {{Wikipedia|Exemplar}} | |||
* {{Wikipedia|Principle_of_least_astonishment}} | |||
</div> | |||
</div> | |||
{{LSLC|Examples|Hex}} | {{LSLC|Examples|Hex}} |
Latest revision as of 14:14, 24 January 2015
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
Function: string hex(integer value);
Returns the hexadecimal nybbles of the signed integer value in order. Specifically returns the nybbles from most to least significant, starting with the first nonzero nybble, folding every nybble to lower case, and beginning with the nonnegative prefix "0x" or the negative prefix "-0x".
Parameters:
• integer | value | – | signed value to be expressed as negative or nonnegative hex |
Note: Always begins any result of eight nybbles with one of the positive signed nybbles 1 2 3 4 5 6 7, never with a zero or unsigned nybble 0 8 9 A B C D E F, except for the boundary test case of the most negative integer "-0x80000000".
Code
The brief, clear, conventional code here implements this specification exactly.
The Efficient Hex article presents an alternative approach: clever, small, and fast code to implement the same specification and related specifications, and also links to instruments that measure small and fast.
// http://wiki.secondlife.com/wiki/hex
string XDIGITS = "0123456789abcdef"; // could be "0123456789ABCDEF"
string hexes(integer bits)
{
string nybbles = "";
while (bits)
{
integer lsn = bits & 0xF; // least significant nybble
string nybble = llGetSubString(XDIGITS, lsn, lsn);
nybbles = nybble + nybbles;
bits = bits >> 4; // discard the least significant bits at right
bits = bits & 0xfffFFFF; // discard the sign bits at left
}
return nybbles;
}
string hex(integer value)
{
if (value < 0)
{
return "-0x" + hexes(-value);
}
else if (value == 0)
{
return "0x0"; // hexes(value) == "" when (value == 0)
}
else // if (0 < value)
{
return "0x" + hexes(value);
}
}
Demo Results
Running the demo should produce exactly these results:
Hello 0x0 == 0 0x400 == (0x00FEDC00 & -0x00FEDC00) 0x40000000 == (1 << 30) -0x80000000 == 0x80000000 -0x123678a == 0xFEDC9876 -0x1 == -1 -0x1 == 0x123456789 OK Hello again 0x7fffffff as base 0x7fffffff by owner 0x0 by group 0x0 by anyone 0x82000 by next owner aka 532480 OK
Demo
To reproduce exactly the expected demo results above, run the demo code below.
We chose test cases that astonish people new to hex and test cases that astonish people new to LSL permission masks.
You'll get the permission mask results we show if you create a New Script to run this demo in. If instead you try modifying some old script to run this demo, then you might have to edit its permission masks to get the demo results that we show here.
default
{
state_entry()
{
llOwnerSay("Hello");
llOwnerSay(hex(0) + " == 0");
llOwnerSay(hex(0x00FEDC00 & -0x00FEDC00) + " == (0x00FEDC00 & -0x00FEDC00)");
llOwnerSay(hex(1 << 30) + " == (1 << 30)");
llOwnerSay(hex(0x80000000) + " == 0x80000000");
llOwnerSay(hex(0xFEDC9876) + " == 0xFEDC9876");
llOwnerSay(hex(-1) + " == -1");
llOwnerSay(hex(0x123456789) + " == 0x123456789");
llOwnerSay("OK");
llOwnerSay("Hello again");
string item = llGetScriptName();
llOwnerSay(hex(llGetInventoryPermMask(item, MASK_BASE)) + " as base");
llOwnerSay(hex(llGetInventoryPermMask(item, MASK_OWNER)) + " by owner");
llOwnerSay(hex(llGetInventoryPermMask(item, MASK_GROUP)) + " by group");
llOwnerSay(hex(llGetInventoryPermMask(item, MASK_EVERYONE)) + " by anyone");
llOwnerSay(hex(llGetInventoryPermMask(item, MASK_NEXT)) + " by next owner");
llOwnerSay("aka " + (string) llGetInventoryPermMask(item, MASK_NEXT));
llOwnerSay("OK");
}
}
Specification
We chose requirements that astonish people who usually write clever, small, or fast code by taking as precedent a specification from the far off world of people who usually write brief, clear, and conventional code.
We require exactly the same results as the hex function of the popular Python scripting language. We thus reproduce how hex integer literals often appear in LSL script, conforming to such arbitrary and traditional AT&T C conventions as:
- return lower case a b c d e f rather than upper case A B C D E F,
- return a signed 31-bit result if negative, rather than an unsigned 32-bit result,
- omit the leading zeroed nybbles, except return "0x0" rather than "0x" when the result is zero,
- return a meaningless "0" before the "x", as LSL and C compilers require,
- return the "x" on the left as in LSL and C, not the "h" on the right as in Assembly code, and
- return the nybbles listed from most to least significant as in English, not listed from least to most significant as in Arabic.
Brief doc for the Python hex function appears buried deep within http://docs.python.org/lib/built-in-funcs.html
Disputes over the detailed specification of the Python hex function appear buried deep within http://www.python.org/dev/peps/pep-0237/
See Also
Articles
Functions
Wikipedia