How to find out the max value for Int in Swift - ios

I want to understand how to access the "struct" type of Int. When I cmd-clicked Int it took me to this class, i want to find out what is the maximum value this can hold. Is there a way to pull from one of this properties ?. what is max and min in this structure ?
struct Int : SignedInteger {
var value: Builtin.Word
init()
init(_ v: Builtin.Word)
init(_ value: Int)
static func convertFromIntegerLiteral(value: Int) -> Int
typealias ArrayBoundType = Int
func getArrayBoundValue() -> Int
static var max: Int { get }
static var min: Int { get }
}

“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.

Try this in Swift 3:
let value = Int.max

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.
from: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html

You can access these as static properties as suggested in other answers.
I see in some comments people are wondering why you can't access them as instance variables.
This is like asking "what is the max value of 5?" and expecting a sensible answer.
One of the main uses for these variables is guarding against integer overflows.
Something along the lines of "if I add something to this integer that makes it bigger than Int.max i.e. it triggers an overflow " and act accordingly.
More on how Apple address the issue of integer overflows here.

Related

Calling C function from Swift shows different results in CLion than in Xcode [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 9 months ago.
Improve this question
I am trying to call a C function from Swift , but I do not know exactly how to define variables to pass parameters. This is the function declaration:
/* Function Declarations */
extern void compute_feature_set(const double input[11025],
double M_data[], int M_size[2],
double D_data[], int D_size[2],
double DD_data[],
int DD_size[2],
double VT[10], double *mp,
double r_42[42], double *fM);
The data is an array of floats. So I tried ​​:
let s = data.compactMap{ Double($0)}
var mSize = Array<Int32>(repeating:Int32(0.0), count:2)
var dSize = Array<Int32>(repeating:Int32(0.0), count:2)
var dD_Size = Array<Int32>(repeating:Int32(0.0), count:2)
var mData = Array<Double>(repeating:0.0, count:48)
var dData = Array<Double>(repeating:0.0, count:48)
var dD_Data = Array<Double>(repeating:0.0, count:48)
var vt = Array<Double>(repeating:0.0, count:10)
var mp = Double(0.0)
var r = Array<Double>(repeating:0.0, count:42)
var fM = Double(0)
compute_feature_set(s, &cout, &mSize, &vx, &dSize, &dD_Data, &dD_Size, &vcta, &mp, &r, &fM)
When I run the code in Clion with the following function it works fine and the output matches the expected values:
static void main_compute_feature_set(void)
{
static double dv[11025];
double DD_data[48];
double D_data[48];
double M_data[48];
double r_42[42];
double VT[10];
double fM;
double mp;
int DD_size[2];
int D_size[2];
int M_size[2];
/* Initialize function 'compute_feature_set' input arguments. */
/* Initialize function input argument 'input'. */
/* Call the entry-point 'compute_feature_set'. */
argInit_11025x1_real_T(dv);
compute_feature_set(dv, M_data, M_size, D_data, D_size,
DD_data, Dd_size, VT,
&mp, r_42, &fM);
}
However, when I run my implementation in Swift, I get very different results.
You could try passing pointers of the Arrays, rather than the Arrays directly.
Using Imported C Functions in Swift | Apple Developer Documentation
Call Functions with Pointer Parameters
Whenever possible, Swift avoids giving you direct access to pointers. When importing C function parameters, however, Swift maps pointer parameters to standard library pointer types.
The following tables use Type as a placeholder type name to indicate syntax for the mappings.
For return types, variables, and arguments, the following mappings apply:
C Syntax
Swift Syntax
const Type *
UnsafePointer<Type>
Type *
UnsafeMutablePointer<Type>
double[] is pretty much equivalent to double * in this case.
Looks like the problem with your code is passing data to your function. You use compactMap to make an Array of Double and then pass the pointer of this array. But Array and Double are struct in Swift so you pass the pointer of struct with structs instead of array of double values.
To convert your data to array of bytes you should use withUnsafeBytes e.g.:
Swift:
let data = Data([0xaa, 0xbb, 0xcc, 0xdd])
data.withUnsafeBytes {
passData($0)
}
C/ObjC:
void passData(const double input[11025]) {
NSLog(#"%x", input[0]); // Prints: ddccbbaa
}

Why can't I convert a Number into a Double?

weight is a field (Number in Firestore), set as 100.
int weight = json['weight'];
double weight = json['weight'];
int weight works fine, returns 100 as expected, but double weight crashes (Object.noSuchMethod exception) rather than returning 100.0, which is what I expected.
However, the following works:
num weight = json['weight'];
num.toDouble();
When parsing 100 from Firestore (which actually does not support a "number type", but converts it), it will by standard be parsed to an int.
Dart does not automatically "smartly" cast those types. In fact, you cannot cast an int to a double, which is the problem you are facing. If it were possible, your code would just work fine.
Parsing
Instead, you can parse it yourself:
double weight = json['weight'].toDouble();
Casting
What also works, is parsing the JSON to a num and then assigning it to a double, which will cast num to double.
double weight = json['weight'] as num;
This seems a bit odd at first and in fact the Dart Analysis tool (which is e.g. built in into the Dart plugin for VS Code and IntelliJ) will mark it as an "unnecessary cast", which it is not.
double a = 100; // this will not compile
double b = 100 as num; // this will compile, but is still marked as an "unnecessary cast"
double b = 100 as num compiles because num is the super class of double and Dart casts super to sub types even without explicit casts.
An explicit cast would be the follwing:
double a = 100 as double; // does not compile because int is not the super class of double
double b = (100 as num) as double; // compiles, you can also omit the double cast
Here is a nice read about "Types and casting in Dart".
Explanation
What happened to you is the following:
double weight;
weight = 100; // cannot compile because 100 is considered an int
// is the same as
weight = 100 as double; // which cannot work as I explained above
// Dart adds those casts automatically
You can do it in one line:
double weight = (json['weight'] as num).toDouble();
You can Parse the data Like given below:
Here document is a Map<String,dynamic>
double opening = double.tryParse(document['opening'].toString());
In Dart, int and double are separate types, both subtypes of num.
There is no automatic conversion between number types. If you write:
num n = 100;
double d = n;
you will get a run-time error. Dart's static type system allows unsafe down-casts, so the unsafe assignment of n to d (unsafe because not all num values are double values) is treated implicitly as:
num n = 100;
double d = n as double;
The as double checks that the value is actually a double (or null), and throws if it isn't. If that check succeeds, then it can safely assign the value to d since it is known to match the variable's type.
That's what's happening here. The actual value of json['weight'] (likely with static type Object or dynamic) is the int object with value 100. Assigning that to int works. Assigning it to num works. Assigning it to double throws.
The Dart JSON parser parses numbers as integers if they have no decimal or exponent parts (0.0 is a double, 0e0 is a double, 0 is an integer). That's very convenient in most cases, but occasionally annoying in cases like yours where you want a double, but the code creating the JSON didn't write it as a double.
In cases like that, you just have to write .toDouble() on the values when you extract them. That's a no-op on actual doubles.
As a side note, Dart compiled to JavaScript represents all numbers as the JavaScript Number type, which means that all numbers are doubles. In JS compiled code, all integers can be assigned to double without conversion. That will not work when the code is run on a non-JS implementation, like Flutter, Dart VM/server or ahead-of-time compilation for iOS, so don't depend on it, or your code will not be portable.
Simply convert int to double like this
int a = 10;
double b = a + 0.0;

Subscript Options in iOS Swift

I have got a tutorial from which I was studying Swift & about Subscript Options. The below is a simple code of documentation's example on this topic.
struct Matrix {
let rows: Int, columns: Int
var print: [Double]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
print = Array(count: rows * columns, repeatedValue: 0.0)
}
subscript(row: Int, column: Int) -> Double {
get {
return print[(row * columns) + column]
}
set {
print[(row * columns) + column] = newValue
}
}
}
var mat = Matrix(rows: 3, columns: 3)
mat[0,0] = 1.0
mat[0,1] = 2.0
mat[1,0] = 3.0
mat[1,1] = 5.0
println("\(mat[0,0])")
println("\(mat[0,1])")
println("\(mat[1,0])")
println("\(mat[1,1])")
Can any one please explain me what is going on here. I am unable to make out about Subscript Options from this example. And might be there would be many like me. Thanks in advance.
Subscripts enable you to query instances of a type by writing one or
more values in square brackets after the instance name. Their syntax
is similar to both instance method syntax and computed property
syntax. You write subscript definitions with the subscript keyword,
and specify one or more input parameters and a return type, in the
same way as instance methods. Unlike instance methods, subscripts can
be read-write or read-only. This behavior is communicated by a getter
and setter in the same way as for computed properties
I think that Apple description is quit good.
If you like Ray Wenderlich - see here.

Does Swift support implicit conversion?

For example, I have the following code:
let numberOfBlocks = 3
let blockWidth = SKSpriteNode(imageNamed: "image.png").size.width
let padding = 20.0
let offsetX : Float = (self.frame.size.width - (blockWidth * numberOfBlocks + padding * (numberOfBlocks-1))) / 2
I got the error:
'Double' is not convertible to 'UInt8'
Is there a way to implicitly convert the data type (maybe only for primitive data type)?
Edit:
I know how to do the explicit conversion by using constructor of particular type as Iducool suggested. But it's not a big help to my question because we even don't know where to add the conversions. I simplified my expression in playground:
The problem is in "padding" variable, the error message is
'Double' is not convertible to 'UInt8'.
So I did the conversion:
Then the problem is in "blockWidth" variable now.
I added the conversion again:
And error message is:
Type 'UInt8' does not conform to protocol 'FloatLiteralCovertible'
The final working expression is:
Is it simple and swift? I don't think so.
There is no implicitly cast in Swift.
Easy way of conversion in swift is using constructor of particular type.
Like if you want to get Float from double then you can use Float(doubleValue) and Same way if you want to convert float to integer then you can use Int(floatValue).
In your case:
let intValue = UInt8(doubleValue)
Beware that you will lose any value after the decimal point. So, choose a better way. Above conversion is just to help you in understanding.
Note that Swift always chooses Double (rather than Float) when inferring the type of floating-point numbers.
Swift doesn't support implicitly cast anymore in Xcode6 GM. Following answer only apply to Xcode6 beta version.
I don't want to talk about implicitly cast is good or bad, but you can have it if you really want with __conversion()
e.g. If you need UInt8 and Int be able to convert from Double
extension Double {
func __conversion() -> UInt8 { return UInt8(self) }
func __conversion() -> Int { return Int(self) }
// add more if you need to
}
xcrun swift
Welcome to Swift! Type :help for assistance.
1> extension Double {
2. func __conversion() -> UInt8 { return UInt8(self) }
3. }
4> var d = 1.0
d: Double = 1
5> var u8 : UInt8 = d
u8: UInt8 = 1
6>
Note: I won't put this in my production code. I only want to point out it if possible but not recommending it.
using bridgeToObjectiveC() method you can call the methods provided in Objective - C to convert from one primitive data type to another for e.g.
variable_name.bridgeToObjectiveC().intValue
will convert that variable named variable_name to integer
Implicit conversion is possible but with literals only and some conversions are available from the box e.g. Int -> Double:
let a = 3 // Int
let b = 100.5 // Double
// Doesn't work with variables
let c = a * b // Error: Binary operator '*' cannot be applied to operands of type 'Int' and 'Double'
// But this works, because Int(3) literal converts to Double(3.0) implicitly
let d = 3 * b // 301.5
If you want to make backward conversion Double -> Int you should extend Int with ExpressibleByFloatLiteral:
extension Int: ExpressibleByFloatLiteral {
public init(floatLiteral value: Double) {
self.init(value)
}
}
// Double(100.5) converts to Int(100)
let e = a * 100.5 // 300
Even more it's possible to implicitly convert to any type from literals, for instance String -> URLRequest:
extension URLRequest: ExpressibleByStringLiteral {
public init(stringLiteral value: String) {
self.init(url: URL(string: value)!)
}
}
let request: URLRequest = "https://www.google.com"

Swift - Convert to absolute value

is there any way to get absolute value from an integer?
for example
-8
to
8
I already tried to use UInt() assuming it will convert the Int to unsigned value but it didn't work.
The standard abs() function works great here:
let c = -8
print(abs(c))
// 8
With Swift 5, you may use one of the two following ways in order to convert an integer to its absolute value.
#1. Get absolute value of an Int from magnitude property
Int has a magnitude property. magnitude has the following declaration:
var magnitude: UInt { get }
For any numeric value x, x.magnitude is the absolute value of x.
The following code snippet shows how to use magnitude property in order to get the absolute value on an Int instance:
let value = -5
print(value.magnitude) // prints: 5
#2. Get absolute value of an Int from abs(_:) method
Swift has a global numeric function called abs(_:) method. abs(_:) has the following declaration:
func abs<T>(_ x: T) -> T where T : Comparable, T : SignedNumeric
Returns the absolute value of the given number.
The following code snippet shows how to use abs(_:) global function in order to get the absolute value on an Int instance:
let value = -5
print(abs(value)) // prints: 5
If you want to force a number to change or keep it positive.
Here is the way:
abs() for int
fabs() for double
fabsf() for float
If you want to get absolute value from a double or Int, use fabs func:
var c = -12.09
print(fabs(c)) // 12.09
c = -6
print(fabs(c)) // 6

Resources