How to calculate the highByte and lowByte of any number;
Example :
let mValue = 26513
hex representation of mValue = 0x6791
Then how find high and low byte of above number?
Updated for swift :
below solution works for me:
let mVal = 26513 // hex value of mVal = 0x6791 (UInt16)
let highByte = (mVal >> 8) & 0xff // hex value of highByte = 0x0067 (UInt8)
let lowByte = mVal & 0xff // hex value of lowByte = 0x0091 (UInt8)
print("highByte: \(highByte)\nLowByte: \(lowByte)")
Related
I'm using bit shift operators on ints to convert to binary representation like that:
String toBinary(int i) {
var bytes = Uint8List(8);
bytes[0] = i >> 56;
bytes[1] = i >> 48;
bytes[2] = i >> 40;
bytes[3] = i >> 32;
bytes[4] = i >> 24;
bytes[5] = i >> 16;
bytes[6] = i >> 8;
bytes[7] = i;
return String.fromCharCodes(bytes);
}
Now I need to do the same thing for doubles, but double does not define bit shift operators. However, as doubles are also represented in 64 bit, is there a way to convert them to binary format?
First of all Dart already provides a ByteData class so in this case you can avoid using the bit shift operation and do instead:
var byteData = ByteData(8);
byteData.setUint64(0, 256);
var bytes = byteData.buffer.asUint8List();
which will produce the same byte list.
Given that you can use the setFloat64 method on ByteData to set a double and then get the binary representation.
EDIT: Resolved, I answered the question below.
I am using the following to get metadata for PHAssets:
let data = NSData.init(contentsOf: url!)!
if let imageSource = CGImageSourceCreateWithData(data, nil) {
let metadata = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)! as NSDictionary
}
The metadata dictionary has all the values I am looking for. However a few fields like ShutterSpeedValue, ExposureTime which have fractions get printed as decimals:
ExposureTime = "0.05"
ShutterSpeedValue = "4.321956769055745"
When I look at this data on my Mac's preview app and exiftool, it shows:
ExposureTime = 1/20
ShutterSpeedValue = 1/20
How can I get the correct fraction string instead of the decimal string?
EDIT: I tried simply converting the decimal to a fraction string using this from SO code but this isn't correct:
func rationalApproximation(of x0 : Double, withPrecision eps : Double = 1.0E-6) -> String {
var x = x0
var a = x.rounded(.down)
var (h1, k1, h, k) = (1, 0, Int(a), 1)
while x - a > eps * Double(k) * Double(k) {
x = 1.0/(x - a)
a = x.rounded(.down)
(h1, k1, h, k) = (h, k, h1 + Int(a) * h, k1 + Int(a) * k)
}
return "\(h)/\(k)"
}
As you notice, the decimal value of ShutterSpeedValue printed as 4.321956769055745 isn't even equal to 1/20.
Resolved.
As per
https://www.dpreview.com/forums/post/54376235
ShutterSpeedValue is defined as APEX value, where:
ShutterSpeed = -log2(ExposureTime)
So -log2(1/20) is 4.3219, just as what I observed.
So to get the ShutterSpeedValue, I use the following:
"1/\(ceil(pow(2, Double(4.321956769055745))))"
I tested 3 different photos and 1/20, 1/15 and 1/1919 were all correctly calculated using your formula.
I obtain magnetometer trim register as get NSData() that looks as follows:
<00001a1a 4f56f202 00000000 1dfd421b>
I need to convert it to Int8, UInt8, Int16, UInt16 depending on which byte I access.
Sources from docs:
s8 dig_x1;/**< trim x1 data */
s8 dig_y1;/**< trim y1 data */
s8 dig_x2;/**< trim x2 data */
s8 dig_y2;/**< trim y2 data */
u16 dig_z1;/**< trim z1 data */
s16 dig_z2;/**< trim z2 data */
s16 dig_z3;/**< trim z3 data */
s16 dig_z4;/**< trim z4 data */
u8 dig_xy1;/**< trim xy1 data */
s8 dig_xy2;/**< trim xy2 data */
u16 dig_xyz1;/**< trim xyz1 data *
The main problem is how to access a selected byte in NSData to convert it manually either to Int8 or UIint16 etc?
Generally, how to approach such problem? Should look for a way to manually iterate over NSData and convert each value manualy as well?
You can convert data.bytes + offset to a pointer of the
appropriate type and then dereference the pointer:
let dig_x1 = UnsafePointer<Int8>(data.bytes).memory
let dig_y1 = UnsafePointer<Int8>(data.bytes + 1).memory
// ...
let dig_z1 = UnsafePointer<UInt16>(data.bytes + 4).memory
let dig_z2 = UnsafePointer<Int16>(data.bytes + 6).memory
// ...
(Note: Here it is assumed that all values in that binary blob are
property aligned for their type.)
The data is in little-endian byte order, which is also what all
current iOS platforms use. To be on the safe side, convert
the data to host byte order explicitly:
let dig_z1 = UInt16(littleEndian: UnsafePointer(data.bytes + 4).memory)
let dig_z2 = Int16(littleEndian: UnsafePointer(data.bytes + 6).memory)
// ...
An alternative is to define a C structure in the bridging header file
struct MagnetometerData {
int8_t dig_x1;
int8_t dig_y1;
int8_t dig_x2;
int8_t dig_y2;
uint16_t dig_z1;
int16_t dig_z2;
int16_t dig_z3;
int16_t dig_z4;
uint8_t dig_xy1;
int8_t dig_xy2;
uint16_t dig_xyz1;
} ;
and extract the data in one step:
var mdata = MagnetometerData()
data.getBytes(&mdata, length: sizeofValue(mdata))
This works (if there is no padding between the struct members)
because Swift preserves the layout of structures imported from C.
A possible Swift 3 implementation of the first approach is
let dig_x1 = ((data as NSData).bytes).load(as: Int8.self)
let dig_y1 = ((data as NSData).bytes + 1).load(as: Int8.self)
// ...
let dig_z1 = ((data as NSData).bytes + 4).load(as: UInt16.self)
let dig_z2 = ((data as NSData).bytes + 6).load(as: Int16.self)
// ...
Again it is assumed that all values are property aligned for their
type.
I'm creating a Swift app in Xcode that sends a command to a BLE adapter in order to make the LED's connected to it change to a different colour.
As I've established from a reply to a previous post on SO, I have to send command in terms of hex integers in an array. I'm using the following code in order to do this:
let bytes : [UInt8] = [ 0x52, 0x13, 0x00, 0x56, 0xFF, 0x00, 0x00, 0x00, 0xAA ]
let data = NSData(bytes: bytes, length: bytes.count)
Therefore, this requires a UInt8 form as suggested above.
However, I'm trying to use sliders as colour pickers on my Swift app in order to set the R, G, and B colours of the LED strip connected to the BLE receiver. In order to do this I have created three sliders for R, G and B respectively, setting the minimum value of each to 0 and the max to 255 (since 255 converts to FF in hex). I'm then using the following function to convert these to hex form for me to implement in the command above.
func colorToHex(input: Int) -> UInt8 {
var st = NSString(format: "%2X", input)
return st
}
The problem with this is the fact that I must return a UInt8 value back again. Since 'st' is an NSString, Xcode throws an error of 'NSString not convertible to UInt8'.
I'm fairly new to Swift. The question here is, how do I get the function to return a UInt8 value how do I get it to form a UInt8 value?
Any help would be greatly appreciated!
There is no need to use NSString or Int. If redSlider is your UISlider with minimum value 0 and maximum value 255 then you can just compute
let redByte = UInt8(redSlider.value)
and use that in your bytes array:
var bytes : [UInt8] = [ 0x52, 0x13, 0x00, 0x56, 0xFF, 0x00, 0x00, 0x00, 0xAA ]
bytes[0] = redByte // Assuming that the first array element is for red.
Just
func colorToHex(input: Int) -> UInt8 {
return UInt8(input % (Int(UInt8.max) + 1))
}
NSString(format: "%2X", colorToHex(25)) // "19"
NSString(format: "%2X", colorToHex(254)) // "FE"
NSString(format: "%2X", colorToHex(255)) // "FF"
NSString(format: "%2X", colorToHex(256)) // "0"
If I were you, I will use NSString(format: "%0x", colorToHex(25)) // "19"
In your case you have space, if the number has one symbol
I've seen a lot of questions converting hex to int, but these are all of the unsigned-> unsigned variety. How could I convert signed hex to an Int?
eg.
somefunc('0xfffff830')
= -2000
Your question implies that you are dealing with 32-bit signed integers
(otherwise 0xfffff830 could not be considered as negative),
so this would work:
let num = "0xfffff830"
let x = Int32(truncatingBitPattern: strtoul(num, nil, 16))
println(x) // -2000
strtoul() converts the hex string to an unsigned integer UInt, and
Int32(truncatingBitPattern:) creates a (signed) 32-bit integer
from the lowest 32 bits of the given argument.
Updated for Swift 4:
let num = "0xfffff830"
let x = Int32(bitPattern: UInt32(num.dropFirst(2), radix: 16) ?? 0)
print(x) // -2000
You could use conversion to unsigned and then convert the unsigned to signed.
let num = "0xfffff830"
var result: UInt32 = 0
let converter = NSScanner(string: num)
converter.scanHexInt(&result)
print(unsafeBitCast(result, Int32.self)) // prints -2000
An approach
var hex = UInt32(0xfffff830)
let signedHex : Int
if hex > UInt32.max / 2 {
signedHex = -Int(~hex + 1) // ~ is the Bitwise NOT Operator
} else {
signedHex = Int(hex)
}