I'm looking Swift alias for Objective-C constant long long int and float numbers.
That is, how can this : 1000LL and .1f be converted into Swift code?
No information found here:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html
You use as-casting when you need to specify literal types in Swift.
1000LL -> 1000 as Int64
.1f -> 0.1 as Float
Related
I like to know, How can I declare and initialize a constant bigger than UInt64 in Swift?
Swift infer seems unable to work for down number. How I should solve this issue?
let number = 11111111222222233333333344444445555555987654321 // Error: overflow
print(number, type(of: number))
Decimal is the numeric type capable of holding the largest value in Swift. However,you can't declare a Decimal literal, since integer literals are inferred to Int, while floating point literals are inferred to Double, so you need to initialise the Decimal from a String literal.
let number = Decimal(string: "321321321155564654646546546546554653334334")!
From the documentation of NSDecimalNumber (whose Swift version is Decimal and hence their numeric range is equivalent):
An instance can represent any number that can be expressed as mantissa x 10^exponent where mantissa is a decimal integer up to 38 digits long, and exponent is an integer from –128 through 127.
If you need to be able to represent arbitrary-length numbers in Swift, you need to use a 3rd party library (or create one yourself), there's no built-in type that could handle this in Swift.
This question already has answers here:
Should conditional compilation be used to cope with difference in CGFloat on different architectures?
(3 answers)
Closed 6 years ago.
Quartz uses CGFloat for its graphics. CGFloat is either Float or Double, depending on the processor.
The Accelerate framework has different variations of the same function.
For example dgetrf_ for Double's and sgetrf_ for Float's.
I have to make these two work together. Either I can use Double's everywhere and convert them to CGFloat every time I use quartz, or I can (try to) determine the actual type of CGFloat and use the appropriate Accelerate function.
Mixing CGFloat's and Double types all over my code base is not very appealing and converting thousands or millions of values to CGFloat every time doesn't strike me as very efficient either.
At this moment I would go with the second option. (Or shouldn't I?)
My question is: how do I know the actual type of CGFloat?
if ??? //pseudo-code: CGFloat is Double
{
dgetrf_(...)
}
else
{
sgetrf_(...)
}
Documentation on Swift Floating-Point Numbers:
Floating-point types can represent a much wider range of values than
integer types, and can store numbers that are much larger or smaller
than can be stored in an Int. Swift provides two signed floating-point
number types:
Double represents a 64-bit floating-point number.
Float represents a 32-bit floating-point number.
You can test using the sizeof function:
if sizeof(CGFloat) == sizeof(Double) {
// CGFloat is a Double
} else {
// CGFloat is a Float
}
Probably the easiest way to deal with this is to use conditional compilation to define a wrapper which will call the proper version:
import Accelerate
func getrf_(__m: UnsafeMutablePointer<__CLPK_integer>,
__n: UnsafeMutablePointer<__CLPK_integer>,
__a: UnsafeMutablePointer<CGFloat>,
__lda: UnsafeMutablePointer<__CLPK_integer>,
__ipiv: UnsafeMutablePointer<__CLPK_integer>,
__info: UnsafeMutablePointer<__CLPK_integer>) -> Int32 {
#if __LP64__ // CGFloat is Double on 64 bit archetecture
return dgetrf_(__m, __n, UnsafeMutablePointer<__CLPK_doublereal>(__a), __lda, __ipiv, __info)
#else
return sgetrf_(__m, __n, UnsafeMutablePointer<__CLPK_real>(__a), __lda, __ipiv, __info)
#endif
}
There is a CGFLOAT_IS_DOUBLE macro defined in Core Graphics. You can use it in Swift for direct comparison:
if CGFLOAT_IS_DOUBLE == 1 {
print("Double")
} else {
print("Float")
}
Of course, direct size comparison is also possible:
if sizeof(CGFloat) == sizeof(Double) {
}
However, since there are overloaded functions for all Float, Double and CGFloat, there is rarely a reason to inspect the size of the type.
Looking at various posts on this topic but still no luck. Is there a simple way to make division/conversion when dividing Double (or Float) with Int? Here is a simple example in playground returning and error "Double is not convertible to UInt8".
var score:Double = 3.00
var length:Int = 2 // it is taken from some an array lenght and does not return decimal or float
var result:Double = (score / length )
Cast the int to double with var result:Double=(score/Double(length))
What this will do is before computing the division it will create a new Double variable with int inside parentheses hence constructor like syntax.
You cannot combine or use different variable types together.
You need to convert them all to the same type, to be able to divide them together.
The easiest way I see to make that happen, would be to make the Int a Double.
You can do that quite simply do that by adding a ".0" on the end of the Integer you want to convert.
Also, FYI:
Floats are pretty rarely used, so unless you're using them for something specific, its also just more fluid to use more common variables.
I need to convert this 50 digit string 53503534226472524250874054075591789781264330331690 into the appropriate number type. I tried this:
let str = "53503534226472524250874054075591789781264330331690"
let num = str.toInt(); // Returns nil
let num = Int64(str.toInt()); // Errors out
The maximimum size of an Int64 is 9,223,372,036,854,775,807 when it is signed. So you cannot convert it just like that.
You need something like the BigInt class found in other languages. Check this other question where they answer with alternatives about BigInt in Swift:
BigInteger equivalent in Swift?
In summary, there are third-party libraries out there for arbitrary long integers. The only alternative from Apple is NSDecimalNumber but its limit is 38 digits, whereas your number has 50.
I have an CGFloat property and sometimes I get a return value of type Float64 or also of type Float32. Could I store both safely to CGFloat?
From the headers:
// CGBase.h
typedef float CGFloat;
// MacTypes.h
typedef float Float32;
typedef double Float64;
So CGFloat and Float32 are both floats while Float64 is a double so you would lose precision.
(Edit to clarify: this is for 32 bit systems such as the iPhone. If you are building for 64 bit, CGFloat is defined as a double.)
It's best practice to always try and store scalar values in the same type as you received them because the precision of scalar types changes with the hardware.
CGFloat isn't always guaranteed to be the same size on all current and future hardware. If you substitute another type for it or use it to store another type, your code made break somewhere down the road.
You might gain or lose precision when a new iPhone/iPad comes out or the code might break if you try to port it to Macs.