Есть ли в 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

Это имеет преимущество теоретического разрешения и неограниченного количества цифр, но имеет тот недостаток, что строки могут не всегда представлять числа.

Другие вопросы по тегам