I have a set of options, some orthogonal (can be combined in any combination), some exclusive (only one from the set is allowed), and need to pick a set of enum values so that they can be combined with bit-wise or and extracted with bit-wise and. I would prefer that or-ing invalid combination would be detectable.
Are there any tools for generating enums like this?
Edit for clarity
I'm looking for something that can leverage the fact that some flags are invalid in combination to reduce the number of bits used. The requirement that I be able to detect errors is soft. I don't need to be able to tell what was used if things are mucked up.
I'm using C#, but any solution should be helpful.
An example pattern would be:
0011 00
0101 00
1001 00
0110 00
1010 00
1100 00
0000 01
0000 10
that gets 6 exclusive flags and an orthogonal pair of 2 into 6 bits
a quick test show that 5-bits gives 9 values, 6-bits give 20,...
The best general method I'm aware of for doing this isn't so much a tool as a convention: defining lists of bitflags like this:
FLAG_1 0x00000001
FLAG_2 0x00000002
FLAG_3 0x00000004
FLAG_4 0x00000008
FLAG_5 0x00000010
FLAG_6 0x00000020
It's easy to work with because the numbers continue on that 1, 2, 4, 8 pattern moving left.
EDIT: Responding to comment. Well, if you really want a combination of bitflags with exclusive enumerations, what you basically have to do is segment out portions of the bit list to be treated as a numeric space. So you can take the two bits 0x1 and 0x2 and now you can represent 0-3 using those two bits. Something like:
OPT_1_VAL_1 0x00000000
OPT_1_VAL_2 0x00000001
OPT_1_VAL_3 0x00000002
OPT_1_VAL_4 0x00000003
FLAG_1 0x00000004
FLAG_2 0x00000008
FLAG_3 0x00000010
FLAG_4 0x00000020
The masking logic you use then has to be more complex. For looking up the flags, you can do if(settings & FLAG_1), but for the option spaces you have to do if((settings & OPT_1_VAL_3) == OPT_1_VAL_3).
To represent an "exclusive" set of n options (i.e. exactly one must be chosen), we require at least ceil(log2(n)) bits. For example, option k can be represented by the number k in base-2.
To represent an "orthogonal" set of n options (i.e. any combination of size 0, 1, ..., n can be chosen), we require at least n bits. For example, options k0, k1, k2 could be represented by the binary number whose bits are zero except for bits 0, 1, 2.
So, to represent multiple option sets simultaneously, we add up the number of bits required for each option set (depending on whether it is "exclusive" or "orthogonal") to get the total number of bits required.
In short, to pick the enum values,
"exclusive" option k uses k << r
"orthogonal" option k0, k1, ..., k{n-1} uses 0x1 << r, 0x1 << (r+1), ..., 0x1 << (r+n-1)
where offset r is the number of bits used by the preceding option sets.
Example of how to automate this construction, in Java:
/**
* Construct a set of enum values, for the given sizes and types
* (exclusive vs orthogonal) of options sets.
*
* #param optionSetSizes
* number of elements in each option set
* #param isOptionSetExclusive
* true if corresponding option set is exclusive, false if
* orthogonal
* #returns
* array of m elements representing the enum values, where
* m is the sum of option set sizes. The enum values are
* given in the order of the option sets in optionSetSizes
* and isOptionSetExclusive.
*/
int[] constructEnumValues(
int[] optionSetSizes,
boolean[] isOptionSetExclusive)
{
assert optionSetSizes.length == isOptionSetExclusive.length;
// determine length of the return value
int m = 0;
for (int i = 0; i < optionSetSizes.length; i++) m += optionSetSizes[i];
int[] vals = new int[m];
int r = 0; // number of bits used by the preceding options sets
int c = 0; // counter for enum values used
for (int i = 0; i < optionSetSizes.length; i++)
{
// size of this option set
int n = optionSetSizes[i];
// is this option set exclusive?
boolean exclusive = isOptionSetExclusive[i];
for (int k = 0; k < n; k++)
{
vals[c] = (exclusive) ? (k << r) : (0x1 << (r + k));
c++;
}
r += (exclusive) ? (int) Math.ceil(Math.log(n)/Math.log(2)) : n;
}
return vals;
}
I don't know of a tool, but here's a trick to make unique-bit enums marginally easier to produce:
public enum Critters
{
Amorphous = 0,
Sloth = 1 << 0,
Armadillo = 1 << 1,
Weasel = 1 << 2,
Crab = 1 << 3,
Partridge = 1 << 4,
Parakeet = 1 << 5,
Rhino = 1 << 6
};
... need to pick a set of enum values
so that they can be combined ...
Do you really need to pick them manually? Java, for instance, has EnumSet which does the dirty work for you and presents you with a Set interface for manipulating these flags.
Use powers of two so that each flag corresponds to a single bit position.
You can use standard enums (in C#) for that purpose. To accomplish this, you need to set the FlagsAttribute, and then specifically number the values. The code would look something like this:
[Flags]
public enum AvailableColours {
black = 1,
red = 2,
green = 4,
blue = 8,
white = 16,
}
And then, the standard bitwise operators will work as expected.
[Edit]
Um, OK, you want to generate possible combinations, right? Your requirements are very specific, so I would be very surprised if there were any tool that came close to what you want. I think you're going to have to roll your own. I'm assuming you want these as strings, correct? Here is some utility code to at least get you started:
public const int BITS_IN_BYTE = 8;
public const int BYTES_IN_INT = sizeof(int);
public const int BITS_IN_INT = BYTES_IN_INT * BITS_IN_BYTE;
/// <summary>
/// Display the bits in an integer
/// </summary>
/// <param name="intToDisplay">The integer to display</param>
/// <returns>A string representation of the bits</returns>
public string IntToBitString(int intToDisplay) {
StringBuilder sb = new StringBuilder();
AppendBitString(intToDisplay, sb);
return sb.ToString();
}
/// <summary>
/// Displays the bits in an integer array
/// </summary>
/// <param name="intsToDisplay">Arrau to display</param>
/// <returns>String representation of the bits</returns>
public string IntArrayToBitString(int[] intsToDisplay) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < intsToDisplay.Length -1; i++) {
AppendBitString(intsToDisplay[i], sb);
sb.Append(' ');
}
if (intsToDisplay.Length - 1 > 0)
AppendBitString(intsToDisplay[intsToDisplay.Length - 1], sb);
return sb.ToString();
}
private void AppendBitString(int intToAppend, StringBuilder sb) {
for (int j = BITS_IN_INT - 1; j >= 0; j--) {
sb.Append((intToAppend >> j) & 1);
if (j % 4 == 0 && j > 1)
sb.Append(' ');
}
}
/// <summary>
/// Creates an integer from a bit string. This method can be used
/// to explicitly set bits in an integer during testing.
/// </summary>
/// <example>
/// int i = bitUtil.IntFromBitString("0000 0000 0000 0100");
/// </example>
/// <param name="bitString">String representing the individual bits</param>
/// <returns></returns>
public int IntFromBitString(String bitString) {
int returnInt = 0;
int currentBitPos = bitString.Length;
for (int i = bitString.Length - 1; i >= 0; i--) {
char c = bitString[i];
if (Char.IsWhiteSpace(c)) continue;
if (c == '1') {
returnInt |= 1 << (bitString.Length - currentBitPos);
}
currentBitPos--;
}
return returnInt;
}
/// <summary>
/// Tests the status of an individual bit in and integer. It is 0 based starting from the most
/// significant bit.
/// </summary>
/// <param name="bits">The integer to test</param>
/// <param name="pos">The position we're interested in</param>
/// <returns>True if the bit is set, false otherwise</returns>
public bool IsBitOn(int bits, int pos) {
int shiftAmnt = (BITS_IN_INT - 1) - pos;
return ((bits >> shiftAmnt) & 1) == 1;
}
/// <summary>
/// Calculates the number of integers (as in an array of ints) required to
/// store a given number of bits
/// </summary>
/// <param name="bitsNeeded">The total count of required bits</param>
/// <returns>The number of integers required to represent a given bit count</returns>
public int RequiredSizeOfIntArray(int bitsNeeded) {
return (bitsNeeded / BITS_IN_INT) + (((bitsNeeded % BITS_IN_INT) == 0) ? 0 : 1);
}
/// <summary>
/// Calculates which array element would hold the individual bit for a given bit position
/// </summary>
/// <param name="bitPos">The position of the interesting bit</param>
/// <returns>An index into an array of integers</returns>
public int ArrayPositionForBit(int bitPos) {
return bitPos / BITS_IN_INT;
}
/// <summary>
/// Sets an individual bit to a given value
/// </summary>
/// <param name="bits">The integer containing the bits</param>
/// <param name="pos">The position in the integer to set</param>
/// <param name="isSet">True for on, False for off</param>
public void SetBit(ref int bits, int pos, bool isSet) {
int posToSet = (BITS_IN_INT - 1) - pos;
if (isSet)
bits |= 1 << posToSet;
else
bits &= ~(1 << posToSet);
}
/// <summary>
/// Converts an array of integers into a comma seperated list
/// of hexidecimal values.
/// </summary>
/// <param name="bits">The array of integers</param>
/// <returns>String format</returns>
public String IntArrayToHexString(int[] bits) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bits.Length - 1; i++) {
sb.Append(bits[i].ToString("X"));
sb.Append(',');
}
if (bits.Length > 0) {
sb.Append(bits[bits.Length - 1].ToString("X"));
}
return sb.ToString();
}
/// <summary>
/// Parses a comma seperated list of hexidecimal values and
/// returns an array of integers for those values
/// </summary>
/// <param name="hexString">Comma seperated hex values</param>
/// <returns>integer array</returns>
public int[] HexStringToIntArray(String hexString) {
string[] hexVals = hexString.Split(new char[] {','});
int[] retInts = new int[hexVals.Length];
for (int i = 0; i < hexVals.Length; i++) {
retInts[i] = Int32.Parse(hexVals[i], System.Globalization.NumberStyles.HexNumber);
}
return retInts;
}
Are you sure you need to use bit fields?
In my experience, a class with a set of boolean data members is almost always the best choice.
The only argument I've ever heard for using bit fields instead of larger booleans (which are often a byte) is that it's supposedly faster. As with all optimizations, doing it without measuring performance is a bad idea.
Once it's encapsulated in a class, if you decide to change representation for optimization, you can do it without hitting a lot of other code.
Related
I have a uint8 array containing ASCII codes for characters and a string variable, and I wish to make a comparison between them. For example:
uint8[3] memory foo = [98, 97, 122]; // baz
string memory bar = "baz";
bool result = keccak256(abi.encodePacked(foo)) == keccak256(abi.encodePacked(bytes(bar))); // false
Here I want the comparison to succeed, but it's a failure because encodePacked will keep the padding of all the uint8 elements in the array when encoding it.
How can I do it instead?
You are currently comparing encoded value abi.encodePacked(foo)) to hashed value keccak256(abi.encodePacked(bytes(bar)), which would never equal.
The uint8 fixed-size array is stored in memory in three separate slots - one for each item - and each of the items is ordered right to left (little endian).
0x
0000000000000000000000000000000000000000000000000000000000000062
0000000000000000000000000000000000000000000000000000000000000061
000000000000000000000000000000000000000000000000000000000000007a
But the string literal is stored as a dynamic-size byte array ordered left to right (big endian):
0x
0000000000000000000000000000000000000000000000000000000000000020 # pointer
0000000000000000000000000000000000000000000000000000000000000003 # length
62617a0000000000000000000000000000000000000000000000000000000000 # value
So because the actual data is stored differently, you cannot perform a simple byte comparison of both arrays.
You can, however, loop through all items of the array and compare each item separately.
pragma solidity ^0.8;
contract MyContract {
function compare() external pure returns (bool) {
uint8[3] memory foo = [98, 97, 122]; // baz
string memory bar = "baz";
// typecast the `string` to `bytes` dynamic-length array
// so that you can use its `.length` member property
// and access its items individually (see `barBytes[i]` below, not possible with `bar[i]`)
bytes memory barBytes = bytes(bar);
// prevent accessing out-of-bounds index in the following loop
// as well as false positive if `foo` contains just the beginning of `bar` but not the whole string
if (foo.length != barBytes.length) {
return false;
}
// loop through each item of `foo`
for (uint i; i < foo.length; i++) {
uint8 barItemDecimal = uint8(barBytes[i]);
// and compare it to each decimal value of `bar` character
if (foo[i] != barItemDecimal) {
return false;
}
}
// all items have equal values
return true;
}
}
How do I write code to convert Binary to Decimal and back in Xcode?
I want to make a binary to decimal calculator, but I don't know how to convert Binary to Decimal in code?
Thank you.
The decimal number is equal to the sum of binary digits times their power of 2.
For eg --> binaryNumber = 10011 (base:2) can be converted to decimal by decimalNumber = (1*(2^4))+(0*(2^3))+(0*(2^2))+(1*(2^1))+(1*(2^0)) (base:10)
I'll write the code in JAVA for your reference
For Binary to Decimal:
public static void main(String [] args){
int binaryNumber = 10011 ;
static int sum = 0;
BinaryToDecimal(binaryNumber,0);
}
//Here we are calculating from right to left
public static void BinaryToDecimal(int number, int power){
int digitAtPosition = number%(10);
sum = sum + (digitAtPosition * (2^(power)));
while(number/10 != 0){
BinaryToDecimal(number/10, power+1);
}
}
Now similarly for Decimal to Binary conversion,
We will have a decimal number. First you will have to keep on dividing the number until the quotient becomes zero. Then from those steps we can get the binary number equivalent of the given decimal.
For eg --> we have a decimalNumber = 13 (base:10).
13/2 Quotient:6 Remainder:1
6/2 Quotient:3 Remainder:0
3/2 Quotient:1 Remainder:1
1/2 Quotient:0 Remainder:1
The binary equivalent is found by writing the remainder numbers from backwards, i,e 1101 (base:2)
In Java (For Decimal to binary)
public static void main(String [] args){
int decimalNumber = 13;
static int [] remainders = new int[size];
static int arrayPos = 0;
DecimalToBinary(decimalNumber);
}
public static DecimalToBinaryConverter(int number){
remainders[arrayPos++]=number%2;
while(number/2 > 0){
DecimalToBinaryConverter(number/2);
}
}
Now if you print the array in reverse you'll get the binary value.
I often use standard function in cpp
sort(A.begin(),A.end(),mycmp)
where,
bool mycmp(int a, int b)
return (a>b);
to sort the vector A. But, when the question asks customized sorting then I often seem confused and take many tries to fix my compare function.Can someone explain that what exactly return (a>b); means; I read some posts also but still cant figure out how a>b determine the order to descending.
posts:
configure the compare function to work with std::sort
You can think cmp as an implementation of less than operator <. I use lt other than < after.
To simplify the question, assume we have bubble sort:
typedef bool (*cmp)(int, int);
bool inc(int a, int b) { return a < b; }
bool dec(int a, int b) { return a > b; }
void bubble_sort(int a[], int n, cmp lt) {
for (int i=0; i<n; ++i) {
for (int j=0; j+1<n-i; ++j) {
if (lt(a[j+1], a[j])) swap(a[j], a[j+1]);
}
}
}
a[j], a[j+1] swaps only if lt(a[j+1],a[j]) is true.
if we pass inc as comparing function, then lt(a[j+1],a[j]) is true means a[j+1]<a[j], so it sorts increasingly.
If we pass dec as comparing function, then lt(a[j+1],a[j]) is true means a[j+1]>a[j], so it sorts decreasingly.
You can check sgi sort implementation for more details.
https://www.sgi.com/tech/stl/sort.html
https://www.sgi.com/tech/stl/download.html
I have the following class (this is not my real class, but just for illustration purposes):
class Number {
public:
Number() : value_(0) {}
explicit Number(int v) : value_(v) {}
Number(const Number & other){
value_ = other.value_;
}
Number& operator=(const int & v){
value_ = v;
return *this;
}
private:
int value_;
};
I can do the following and they all work correctly:
void test_ok(){
Number x(3);
Number y = Number(3);
Number y2(x);
Number y3 = x;
Number u;
u = 3;
}
However, the following gives this compiler error: no suitable constructor exists to convert from "int" to "Number"
void test_error(){
Number z = 3;
}
If I comment the word "explicit" from the second constructor, then the compiler error is gone and apparently the automatic conversion works fine. Since I would like to keep the keyword "explicit", which constructor am I missing?
Thanks in advance!
The explicit keyword prohibits implicit automatic typecasting. In your test Number z = 3 you're doing exactly that - implicit typecasting, from an int (3) to a Number. The compiler rightfully prohibits that.
If you want to keep the keyword explicit then you'll have to construct the Number object as Number(3) (as you'd already noticed and written).
In short, there is no other constructor that you can use if you want to keep the explicit keyword. Whatever you do, implicit typecasts will be prohibited.
In C# I've been trying to come up with an interesting way to basically accomplish the following, but without using the string representation.
private static bool HasZeroDigit(int value)
{
string text = value.ToString();
if (text.Contains("0"))
{
return true;
}
return false;
}
My first attempt was some trickery along the lines of checking if a byte in the binary representation of the absolute value contains a zero byte, but obviously that doesn't map correctly. Though it got me thinking if this would be on the right track with some adjustment for how integers map to individual characters.
My incorrect first attempt:
private static bool HasZeroDigit(int value)
{
uint temp = value >= 0 ? (uint)value : (uint)-value;
if (temp <= UInt16.MaxValue)
{
ushort temp16 = (ushort)temp;
return ~((((temp16 & 0x7F7F) + 0x7F7F) | temp16) | 0x7F7F) != 0;
}
bool hasZero = ~((((temp & 0x7F7F7F7F) + 0x7F7F7F7F) | temp) | 0x7F7F7F7F) != 0;
return hasZero;
}
So, is there a way to check if an integer contains a zero digit without actually turning it into a string? The goal here is computational efficiency.
Suggestions and solutions in any language are welcome.