Why UInt64.max / 2 + 1 represented in the memory the same as Int64 value -9 223 372 036 854 775 808 but not as -1?
Yes, in fact -1
is not represented as 1
with a sign bit, but rather as all bits set to one. This is called a "two's complement" representation, and is used in most of the modern processors.
Read more about it here:
https://en.wikipedia.org/wiki/Two%27s_complement
One of the reasons for that is that this way arithmetic operations that involve both negative and positive numbers are easier. If -1
was represented as 1
with a sign bit, and we attempted to add 1
to it in a naive way, we would get 2
with a sign bit instead of zero. With two's complement representation you can just add the numbers as if they were unsigned, and get the correct result.
Swift - UInt behaviour
Apparently this is just a bug in swift playground and according to @Anton, printing the variables shows the correct value.
Weird UInt64 behavior in Swift
That looks like a bug to me.
let p1 = pow(Double(2), Double(64))
is greater than UInt64.max
, therefore
let x1 = UInt64(p1)
should crash (or perhaps return UInt64.max
as an approximation).
The "next smaller" floating point double variable
let p2 = nextafter(p1, 0.0)
let x2 = UInt64(p2)
// 18446744073709549568
is converted correctly, and the "next larger" floating point double variable
fails correctly to convert
let p3 = nextafter(p1, DBL_MAX)
let x3 = UInt64(p3)
// fatal error: floating point value can not be converted to UInt64
// because it is greater than UInt64.max
Unable to convert UInt64 to hexadecimal?
I've no idea what PRIx64 is. I did this:
uint64_t t = 586512487604551679;
NSString* s = [NSString stringWithFormat:@"%llx", t];
NSLog(@"%@", s); // 823b5ffffffffff
and
let t : UInt64 = 586512487604551679
let s = String(t, radix:16)
print(s) // 823b5ffffffffff
How to find out the max value for Int in Swift
“You can access the minimum and maximum values of each integer type with its min and max properties:
let minValue = UInt8.min // minValue is equal to 0, and is of type UInt8
let maxValue = UInt8.max // maxValue is equal to 255, and is of type UInt8
The values of these properties are of the appropriate-sized number type (such as UInt8 in the example above) and can therefore be used in expressions alongside other values of the same type.”
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/in/jEUH0.
How to convert NSDecimalNumber to byte array if NSDecimalNumber is bigger than Uint64?
The problem is obviously the use of uint64Value
, which obviously cannot represent any value greater than UInt64.max
, and your example, 59,785,897,542,892,656,787,456, is larger than that.
If you want to grab the byte representations of the 128 bit mantissa, you can use _mantissa
tuple of UInt16
words of Decimal
, and convert them to bytes if you want. E.g.
extension Decimal {
var byteArray: [UInt8] {
return [_mantissa.0,
_mantissa.1,
_mantissa.2,
_mantissa.3,
_mantissa.4,
_mantissa.5,
_mantissa.6,
_mantissa.7]
.flatMap { [UInt8($0 & 0xff), UInt8($0 >> 8)] }
}
}
And
if let foo = Decimal(string: "59785897542892656787456") {
print(foo.byteArray)
}
Returning:
[0, 0, 0, 0, 0, 0, 0, 0, 169, 12, 0, 0, 0, 0, 0, 0]
This, admittedly, only defers the problem, breaking the 64-bit limit of your uint64Value
approach, but is still constrained to the inherent 128-bit limit of NSDecimalNumber
/Decimal
. To capture numbers greater than 128 bits, you'd need a completely different representation.
NB: This also assumes that the exponent is 0
. If, however, you had some large number, e.g. 4.2e101 (4.2 * 10101), the exponent will be 100
and the mantissa will simply be 42
, which I bet is probably not what you want in your byte array. Then again, this is an example of a number that is too large to represent as a single 128 bit integer, anyway:
if let foo = Decimal(string: "4.2e101") {
print(foo.byteArray)
print(foo.exponent)
}
Yielding:
[42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
100
How to find max value for Double and Float in Swift
As of Swift 3+, you should use:
CGFloat.greatestFiniteMagnitude
Double.greatestFiniteMagnitude
Float.greatestFiniteMagnitude
Related Topics
Set Insets to the Collectionview Programmatically in Swift
Type of Optionals Cannot Be Inferred Correctly in Swift 2.2
Enum Not Working in Custom Initializer
How to Scale/Position Nodes Swift Spritekit? Custom View
Swift Error: 'Sequence' Requires the Types 'T' and 'Arrayslice<T>' Be Equivalent
Codable/Decodable Should Decode Array with Strings
Swiftui List View Not Updating After Core Data Entity Updated in Another View
Charts Not Plotting in Tableviewcell
Comparing Two Enum Variables Regardless of Their Associated Values
Create Endless Cgpath Without Framedrops
Apple Push Notifications Without Developer Account
Swiftui Nested Foreach Causes Unexpected Ordering
How to Create a Portal Effect in Arkit Just Using the Scenekit Editor
Fail to Import Restkit with Cocoapods Dynamic Frameworks
Swift Error Comparing Two Arrays of Optionals
Why There Is a Overflow with Swift Language When Assign a 8 Bits Binary Value to a Var of Int8 Type