Есть ли в Swift тип чисел с большей емкостью, чем u_long/UInt64?
Есть ли в Swift тип с большей емкостью, чем u_long или UInt64?
У меня есть функция, которая принимает очень большие целые числа для определения номера кредитной карты с 28 цифрами:
func myFunc(number : /*What to put here?*/) {
//body
}
какой тип подходит? номер должен рассматриваться как строка?
4 ответа
Номер кредитной карты не является числом в значимом математическом смысле. Это последовательность цифр, а CC следует рассматривать как текст, очень похожий на номер телефона. Одной из непосредственных проблем использования целочисленного значения фиксированной длины является то, что код не может одновременно обнаруживать начальные и конечные нули по "отсутствующим числам".
Используйте строку или определенный (пользовательский) тип, представляющий номер CC, возможно, используя строку внутри. Длина числа (в base-10) будет тогда тривиально количеством цифр: которое является длиной основной строки.
Номер СС (представленный истинной строкой) может быть позже закодирован в соответствующее двоичное представление, если (и когда) требуется.
Вы можете реализовать свой собственный UInt128
тип. Или использовать NSDecimalNumber
Реализовать UInt128
struct UInt128 {
var low : UInt64 = 0;
var high : UInt64 = 0;
}
и вы можете реализовать операторы
infix func + (l: UInt128, r: UInt128) -> UInt128 {
// do your work... care with overflow
}
Я работаю над библиотекой BigNumber, с помощью которой вы можете выполнять вычисления большого числа. На самом деле библиотека основана на библиотеке GNU Multiple Precision (GMP) (см.: https://gmplib.org/), и я написал оболочку Objective-C / Swift. В настоящее время возможна большая целочисленная математика, включающая много перегрузок операторов. Пример кода выглядит так:
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())")
что приводит к:
Multiply 2 BigInts: bi1 * bi2 = 153933852140173822960829726365674325601913839520
Вы можете найти библиотеку по адресу: https://github.com/githotto/osxgmp
Я думаю, что довольно легко сделать некоторую математику "номер кредитной карты" с четными числами, имеющими намного больше чем 28 цифр.
Другой подход заключается в работе со строками и определении математических операторов для работы со строками:
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
Это имеет преимущество теоретического разрешения и неограниченного количества цифр, но имеет тот недостаток, что строки могут не всегда представлять числа.