Decomposing a number into powers of 2 - swift

Hi I need to decompose a number into powers of 2 in swift 5 for an iOS app I'm writing fro a click and collect system.
The backend of this system is written in c# and uses the following to save a multi-pick list of options as a single number in the database eg:
choosing salads for a filled roll on an order system works thus:
lettuce = 1
cucumber = 2
tomato = 4
sweetcorn = 8
onion = 16
by using this method it saves the options into the database for the choice made as (lettuce + tomato + onion) = 21 (1+4+16)
at the other end I use a c# function to do this thus:
for(int j = 0; j < 32; j++)
{
int mask = 1 << j;
}
I need to convert this function into a swift 5 format to integrate the decoder into my iOS app
any help would be greatly appreciated

In Swift, these bit fields are expressed as option sets, which are types that conform to the OptionSet protocol. Here is an example for your use case:
struct Veggies: OptionSet {
let rawValue: UInt32
static let lettuce = Veggies(rawValue: 1 << 0)
static let cucumber = Veggies(rawValue: 1 << 1)
static let tomato = Veggies(rawValue: 1 << 2)
static let sweetcorn = Veggies(rawValue: 1 << 3)
static let onion = Veggies(rawValue: 1 << 4)
}
let someVeggies: Veggies = [.lettuce, .tomato]
print(someVeggies) // => Veggies(rawValue: 5)
print(Veggies.onion.rawValue) // => 16
OptionSets are better than just using their raw values, for two reasons:
1) They standardize the names of the cases, and gives a consistent and easy way to interact with these values
2) OptionSet derives from the SetAlgebra protocol, and provides defaulted implementations for many useful methods like union, intersection, subtract, contains, etc.
I would caution against this design, however. Option sets are useful only when there's a really small number of flags (less than 64), that you can't forsee expanding. They're really basic, can't store any payload besides "x exists, or it doesn't", and they're primarily intended for use cases that have very high sensitivity for performance and memory use, which quick rare these days. I would recommend using regular objects (Veggie class, storing a name, and any other relevant data) instead.

You can just use a while loop, like this :
var j = 0
while j < 32 {
var mask = 1 << j
j += 1
}
Here is a link about loops and control flow in Swift 5.

Hi I figured it out this is my final solution:
var salads = "" as String
let value = 127
var j=0
while j < 256 {
let mask=1 << j
if((value & mask) != 0) {
salads.append(String(mask) + ",")
}
j += 1
}
salads = String(salads.dropLast()) // removes the final ","
print(salads)
This now feeds nicely into the in clause in my SQL query, thanks you all for your help! :)

Related

How to generate a model for my code using boolector?

I'm experimenting a bit with boolector so I'm trying to create model for simple code. Suppose that I have the following pseudo code:
int a = 5;
int b = 4;
int c = 3;
For this simple set of instructions I can create the model and all works fine. The problem is when I have other instructions after that like
b = 10;
c = 20;
Obviously it fails to generate the model because b cannot be equal to 4 and 10 within the same module. One of the maintainer suggested me to use boolector_push and boolector_pop in order to create new Contexts when needed.
The code for boolector_push is :
void
boolector_push (Btor *btor, uint32_t level)
{
BTOR_ABORT_ARG_NULL (btor);
BTOR_TRAPI ("%u", level);
BTOR_ABORT (!btor_opt_get (btor, BTOR_OPT_INCREMENTAL),
"incremental usage has not been enabled");
if (level == 0) return;
uint32_t i;
for (i = 0; i < level; i++)
{
BTOR_PUSH_STACK (btor->assertions_trail,
BTOR_COUNT_STACK (btor->assertions));
}
btor->num_push_pop++;
}
Instead for boolector_pop is
void
boolector_pop (Btor *btor, uint32_t level)
{
BTOR_ABORT_ARG_NULL (btor);
BTOR_TRAPI ("%u", level);
BTOR_ABORT (!btor_opt_get (btor, BTOR_OPT_INCREMENTAL),
"incremental usage has not been enabled");
BTOR_ABORT (level > BTOR_COUNT_STACK (btor->assertions_trail),
"can not pop more levels (%u) than created via push (%u).",
level,
BTOR_COUNT_STACK (btor->assertions_trail));
if (level == 0) return;
uint32_t i, pos;
BtorNode *cur;
for (i = 0, pos = 0; i < level; i++)
pos = BTOR_POP_STACK (btor->assertions_trail);
while (BTOR_COUNT_STACK (btor->assertions) > pos)
{
cur = BTOR_POP_STACK (btor->assertions);
btor_hashint_table_remove (btor->assertions_cache, btor_node_get_id (cur));
btor_node_release (btor, cur);
}
btor->num_push_pop++;
}
In my opinion, those 2 functions maintains track of the assertions generated using boolector_assert so how is it possible to obtain the final and correct model using boolector_push and boolector_pop considering that the constraints are going to be the same?
What am I missing?
Thanks
As you suspected, solver's push and pop methods aren't what you're looking for here. Instead, you have to turn the program you are modeling into what's known as SSA (Static Single Assignment) form. Here's the wikipedia article on it, which is quite informative: https://en.wikipedia.org/wiki/Static_single_assignment_form
The basic idea is that you "treat" your mutable variables as time-varying values, and give them unique names as you make multiple assignments to them. So, the following:
a = 5
b = a + 2
c = b + 3
c = c + 1
b = c + 6
becomes:
a0 = 5
b0 = a0 + 2
c0 = b0 + 3
c1 = c0 + 1
b1 = c1 + 6
etc. Note that conditionals are tricky to deal with, and generally require what's known as phi-nodes. (i.e., merging the values of branches.) Most compilers do this sort of conversion automatically for you, as it enables many optimizations down the road. You can either do it by hand, or use an algorithm to do it for you, depending on your particular problem.
Here's another question on stack-overflow, that's essentially asking for something similar: Z3 Conditional Statement
Hope this helps!

EditorGuiLayout.MaskField issue with large enums

I'm working on an input system that would allow the user to translate input mappings between different input devices and operating systems and potentially define their own.
I'm trying to create a MaskField for an editor window where the user can select from a list of RuntimePlatforms, but selecting individual values results in multiple values being selected.
Mainly for debugging I set it up to generate an equivalent enum RuntimePlatformFlags that it uses instead of RuntimePlatform:
[System.Flags]
public enum RuntimePlatformFlags: long
{
OSXEditor=(0<<0),
OSXPlayer=(0<<1),
WindowsPlayer=(0<<2),
OSXWebPlayer=(0<<3),
OSXDashboardPlayer=(0<<4),
WindowsWebPlayer=(0<<5),
WindowsEditor=(0<<6),
IPhonePlayer=(0<<7),
PS3=(0<<8),
XBOX360=(0<<9),
Android=(0<<10),
NaCl=(0<<11),
LinuxPlayer=(0<<12),
FlashPlayer=(0<<13),
LinuxEditor=(0<<14),
WebGLPlayer=(0<<15),
WSAPlayerX86=(0<<16),
MetroPlayerX86=(0<<17),
MetroPlayerX64=(0<<18),
WSAPlayerX64=(0<<19),
MetroPlayerARM=(0<<20),
WSAPlayerARM=(0<<21),
WP8Player=(0<<22),
BB10Player=(0<<23),
BlackBerryPlayer=(0<<24),
TizenPlayer=(0<<25),
PSP2=(0<<26),
PS4=(0<<27),
PSM=(0<<28),
XboxOne=(0<<29),
SamsungTVPlayer=(0<<30),
WiiU=(0<<31),
tvOS=(0<<32),
Switch=(0<<33),
Lumin=(0<<34),
BJM=(0<<35),
}
In this linked screenshot, only the first 4 options were selected. The integer next to "Platforms: " is the mask itself.
I'm not a bitwise wizard by a large margin, but my assumption is that this occurs because EditorGUILayout.MaskField returns a 32bit int value, and there are over 32 enum options. Are there any workarounds for this or is something else causing the issue?
First thing I've noticed is that all values inside that Enum is the same because you are shifting 0 bits to left. You can observe this by logging your values with this script.
// Shifts 0 bits to the left, printing "0" 36 times.
for(int i = 0; i < 36; i++){
Debug.Log(System.Convert.ToString((0 << i), 2));
}
// Shifts 1 bits to the left, printing values up to 2^35.
for(int i = 0; i < 36; i++){
Debug.Log(System.Convert.ToString((1 << i), 2));
}
The reason inheriting from long does not work alone, is because of bit shifting. Check out this example I found about the issue:
UInt32 x = ....;
UInt32 y = ....;
UInt64 result = (x << 32) + y;
The programmer intended to form a 64-bit value from two 32-bit ones by shifting 'x' by 32 bits and adding the most significant and the least significant parts. However, as 'x' is a 32-bit value at the moment when the shift operation is performed, shifting by 32 bits will be equivalent to shifting by 0 bits, which will lead to an incorrect result.
So you should also cast the shifting bits. Like this:
public enum RuntimePlatformFlags : long {
OSXEditor = (1 << 0),
OSXPlayer = (1 << 1),
WindowsPlayer = (1 << 2),
OSXWebPlayer = (1 << 3),
// With literals.
tvOS = (1L << 32),
Switch = (1L << 33),
// Or with casts.
Lumin = ((long)1 << 34),
BJM = ((long)1 << 35),
}

How to use sizeof() method in Swift 4

I am trying to implement this code which I got from an apple WWDC video. However the video is from 2016 and I think the syntax has changed. How do I call sizeof(Float)? This produces an error.
func render(buffer:AudioBuffer){
let nFrames = Int(buffer.mDataByteSize) / sizeof(Float)
var ptr = UnsafeMutableRawPointer(buffer.mData)
var j = self.counter
let cycleLength = self.sampleRate / self.frequency
let halfCycleLength = cycleLength / 2
let amp = self.amplitude, minusAmp = -amp
for _ in 0..<nFrames{
if j < halfCycleLength{
ptr.pointee = amp
} else {
ptr.pointee = minusAmp
}
ptr = ptr.successor()
j += 1.0
if j > cycleLength {
}
}
self.counter = j
}
The sizeof() function is no longer supported in Swift.
As Leo Dabus said in his comment, you want MemoryLayout<Type>.size, or in your case, MemoryLayout<Float>.size.
Note that tells you the abstract size of an item of that type. However, due to alignment, you should not assume that structs containing different types of items will be the sums of the sizes of the other elements. Also, you need to consider the device it's running on. On a 64 bit device, Int is 8 bytes. On a 32 bit device, it's 4 bytes.
See the article on MemoryLayout at SwiftDoc.org for more information.

Swift Sensortag 2.0 Write Bits to BLE

Pretty basic question here:
I'm currently trying to control a sensortag 2.0 via Swift 3.0.
I'm trying to simultaneously turn on the acc, gyro, and magnetometer.
According to Texas Instruments documentation, the following applies for the IMU:
Axis enable bits:gyro-z=0,gyro-y,gyro-x,acc-z=3,acc-y,acc-x,mag=6 Range: bit 8,9
I have written "0x023F" in the following manner, which turns on the gyro and the accelerometer with great success.
let value = OperationDataHolder(data:[0x023F])
var parameter = 0x023F
let data = NSData(bytes: &parameter, length: 2)
self.sensorTagPeripheral.writeValue(data as Data, for: thisCharacteristic, type: CBCharacteristicWriteType.withResponse)
However, I'm not able to figure out the value to write to turn turn on all 3 units simultaneously. Would someone be able to provide me with this value?
Thanks!
When you convert the current value you are using (0x023F) to binary, you get 0b1000111111. Each of the bits represents the on/off (on=1/off=0) state of a given sensor component.
If you read the binary number from right to left, and map each bit by referencing the table below, you will see that the gyro z/y/x and accelerometer z/y/x are all enabled. If you want to enable the magnetometer, simply change 'bit 6' to a '1' and convert that binary number to a hexadecimal number.
So, Google says: 0b1001111111 is 0x027F in hexadecimal
Mapping:
bit 0 => gyro z-axis
bit 1 => gyro y-axis
bit 2 => gyro x-axis
bit 3 => acc z-axis
bit 4 => acc y-axis
bit 5 => acc x-axis
bit 6 => mag (enables all axes)
bit 7 => Wake-on-motion enable
bits 8 & 9 => Accelerometer range
bits 10-15 => not used
For more info about the mapping (i.e. what bits 8 & 9 do), see the Sensor Tag Wiki Page
Building on peters answer, the swifty way to do this is with an option set, which is admittedly more work up front, but much more readable than hex:
struct SensorOptions: OptionSet {
let rawValue: Int32
static let gyroZ = SensorOptions(rawValue: 1 << 0)
static let gyroY = SensorOptions(rawValue: 1 << 1)
static let gyroX = SensorOptions(rawValue: 1 << 2)
static let accZ = SensorOptions(rawValue: 1 << 3)
static let accY = SensorOptions(rawValue: 1 << 4)
static let accX = SensorOptions(rawValue: 1 << 5)
static let mag = SensorOptions(rawValue: 1 << 6)
static let wakeOnMotion = SensorOptions(rawValue: 1 << 7)
static let accelerometerRange1 = SensorOptions(rawValue: 1 << 8)
static let accelerometerRange2 = SensorOptions(rawValue: 1 << 9)
}
let options: SensorOptions = [.gyroZ, .gyroY, .gyroX, .accZ, .accY, .accX, .mag, .accelerometerRange2]
var parameter = options.rawValue
let data = NSData(bytes: &parameter, length: 2)
self.sensorTagPeripheral.writeValue(data as Data, for: thisCharacteristic, type: CBCharacteristicWriteType.withResponse)
Also if you don't like the option set swift has binary literals so you can write var parameter = 0b1001111111 in your code instead of 0x027F

How to interpret document.state == 12 (iCloud)

Whenever I load a UIDocument from iCloud, I check its state like so:
NSLog(#"Library loadFromContents: state = %d", self.documentState);
In some cases I have received documentState 8 or 12 which have caused crashes. I am now wondering what exactly the 8 and 12 stands for. As far as I'm aware, documentState is a bit field, so it has many different flags. The docs reveal that:
enum {
UIDocumentStateNormal = 0,
UIDocumentStateClosed = 1 << 0,
UIDocumentStateInConflict = 1 << 1,
UIDocumentStateSavingError = 1 << 2,
UIDocumentStateEditingDisabled = 1 << 3 };
typedef NSInteger UIDocumentState;
However, I have no idea how to interpret this in my situation. How do I find out what 8 and 12 stand for?
Inside the enum they do some bit-shifting. They could have also written it like this:
enum {
UIDocumentStateNormal = 0,
UIDocumentStateClosed = 1,
UIDocumentStateInConflict = 2,
UIDocumentStateSavingError = 4,
UIDocumentStateEditingDisabled = 8 };
typedef NSInteger UIDocumentState;
A bit shift to the left is basically 2 to the power of whatever number is given after the shift operator... 1<<1 means 2^1, 1<<2 means 2^2, etc ...
A state of 8 means UIDocumentStateEditingDisabled and 12 means UIDocumentStateEditingDisabled and UIDocumentStateSavingError
The suggested way to deal with these notifications is to not check for if(state == UIDocumentStateInConflict) but with a logical AND like this:
if (state & UIDocumentStateInConflict) {
// do something...
}
see "An Example: Letting the User Pick the Version" in "Document-based app programming guide" from the official docs