Is there a type type with more capacity than u_long / UInt64 in Swift?
Is there a type with more capacity than u_long or UInt64 in Swift?
I have a function that takes very large integers to identify a 28-digit credit card number:
func myFunc(number : /*What to put here?*/) {
//body
}
which type is suitable? should the number be treated as a string?
A credit card number is not a number in a meaningful mathematical sense. It is a sequence of numbers, and CC should be treated like text, like a telephone number. One of the pressing problems of using a fixed length integer value is that the code cannot simultaneously detect leading and trailing zeros from "no more numbers present".
Use a string or specific (custom) type representing the CC number, perhaps using an internal string. The length of the number (in base-10) is then trivially equal to the number of digits: this is the length of the underlying string.
The CC number (represented by the string bonafide) can subsequently be encoded into the appropriate binary representation if required (and when).
You can implement your own type UInt128
. Or useNSDecimalNumber
To realize UInt128
struct UInt128 {
var low : UInt64 = 0;
var high : UInt64 = 0;
}
and you can implement the operators
infix func + (l: UInt128, r: UInt128) -> UInt128 {
// do your work... care with overflow
}
I am working on BigNumber library with which you can do large number calculations. In fact the library is based on the GNU Multiple Precision (GMP) library (see https://gmplib.org ) and I wrote an Objective-C / Swift wrapper.A lot of whole math is possible nowadays, including a lot of operator overloading. Sample code looks like this:
var err : NSError?
var bi1 = BigInt(nr: 12468642135797531)
var bi2 = BigInt(nr: "12345678901011121314151617181920", error: &err)
var res = bi1 * bi2
println("Multiply 2 BigInts: bi1 * bi2 = \(res.toString())")
that leads to:
Multiply 2 BigInts: bi1 * bi2 = 153933852140173822960829726365674325601913839520
You can find the library at: https://github.com/githotto/osxgmp
I think its pretty easy to do "credit card" math with even numbers having a lot more 28 digits.
Another approach would be to work with strings and define mathematical operators to work with strings:
func +(lhs: String, rhs: Int8) -> String
func +(lhs: String, rhs: Int16) -> String
func +(lhs: String, rhs: Int32) -> String
func +(lhs: String, rhs: Int64) -> String
func +(lhs: String, rhs: String) -> String
// ... other operators
This has the advantage of theoretically allowing an unlimited number of digits, but has the disadvantage that strings may not always represent numbers.
In 2019, the take is very large.
import Foundation
print("Double \(Double.greatestFiniteMagnitude)")
print("NSDecimalNumber \(NSDecimalNumber.maximum)")
let countByHand = "\(NSDecimalNumber.maximum)".count - 1
print("NSDecimalNumber zeroes \(countByHand)")
print("Float \(Float.greatestFiniteMagnitude)")
print("UInt \(UInt.max)")
produces
Double 1.7976931348623157e+308
NSDecimalNumber 3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
NSDecimalNumber zeroes 165
Float 3.4028235e+38
UInt 18446744073709551615
I'm not sure if it has changed since 2014 or ...?