ios - 当超过 20 位的大整数时,为什么 Swift 5 String(Int) 会失败?
问题描述
我编写了上面引用的简单代码来检查斐波那契数列中的整数是否不包含 0 或 5,如果整数仅包含 1、2、3、4、6、7、8 或 9,则减少到 1237数字; 如果是,则打印序列的成员。有趣的是,从数字游戏的角度来看,斐波那契数列中只有 23 个这样的整数。
当整数变大时,我必须使用Swift-BigInt库:
func getFib1237s() {
// Some temporary variables.
var a = BInt(0)
var b = BInt(1)
var m = BInt(1)
var i = BInt(0)
var z = BInt(1)
// Get the numbers until crash...
while i < z {
let temp = a
a = b
b = b + temp
print("a: ", a)
var str = String(a)
print("String start: ", str)
str = str.replacingOccurrences(of: "9", with: "3")
print("String after 9 reducto: ", str)
str = str.replacingOccurrences(of: "6", with: "23")
print("String after 6 reducto: ", str)
str = str.replacingOccurrences(of: "8", with: "2")
print("String after 8 reducto: ", str)
str = str.replacingOccurrences(of: "4", with: "2")
print("String after 4 reducto: ", str)
if (str.firstIndex(of:"5") == nil) && (str.firstIndex(of: "0") == nil) && str.contains("1") && str.contains("2") && str.contains("3") && str.contains("7") {
print(m, "Fib 1237 number is ", a, " | Digits: ", str.count)
m+=1
}
i+=1
z+=1
}
}
显然,在 20 位标记处或附近,该String()
方法失败并抛出错误,不执行检查,因为根据调试器,整数被完全更改为随机的其他整数。
那么,Swift 中是否有任何BigInt
解决String
方法/替代方案?我编写了在 Xcode 中运行良好的 Ruby 代码,但我试图为这个项目专门使用 Swift(和 metal),该项目最终需要在 iOS 上运行以用于商业/生产目的。
解决方案
String(a)
调用需要的String.init
重载BinaryInteger
。这个初始化器很可能不是为处理超大数字而设计的。您可以改用a.asString(radix: 10)
转换为字符串。
为了使您的代码正常工作,您还应该:
- 去除
(str.firstIndex(of: "0") == nil)
- 声明一个新的字符串变量并将替换的字符串分配给它,否则
str.count
将是不正确的。
我建议编写一个名为 的单独方法reduce
,因为“减少”字符串需要很多步骤。
这里是reduce
:
func reduce(_ s: String) -> String {
let unique = String(Set(s))
let replaced = unique.replacingOccurrences(of: "9", with: "3")
.replacingOccurrences(of: "6", with: "23")
.replacingOccurrences(of: "8", with: "2")
.replacingOccurrences(of: "4", with: "2")
.replacingOccurrences(of: "0", with: "")
let sortedUniqueAgain = String(Set(replaced).sorted())
return sortedUniqueAgain
}
现在,我们可以检查该方法的返回值是否为 1237:
while m <= 23 {
let temp = a
a = b
b = b + temp
let str = a.asString(radix: 10)
// note that I have declared a new let constant here, instead of assigning to str
// because otherwise str.count will be wrong
let reduced = reduce(str)
if reduced == "1237" {
print(m, "Fib 1237 number is ", a, " | Digits: ", str.count)
m+=1
}
}
输出:
1 Fib 1237 number is 317811 | Digits: 6
2 Fib 1237 number is 2178309 | Digits: 7
3 Fib 1237 number is 267914296 | Digits: 9
4 Fib 1237 number is 701408733 | Digits: 9
5 Fib 1237 number is 1134903170 | Digits: 10
6 Fib 1237 number is 72723460248141 | Digits: 14
7 Fib 1237 number is 117669030460994 | Digits: 15
8 Fib 1237 number is 8944394323791464 | Digits: 16
9 Fib 1237 number is 14472334024676221 | Digits: 17
10 Fib 1237 number is 37889062373143906 | Digits: 17
11 Fib 1237 number is 420196140727489673 | Digits: 18
12 Fib 1237 number is 1100087778366101931 | Digits: 19
13 Fib 1237 number is 1779979416004714189 | Digits: 19
14 Fib 1237 number is 2880067194370816120 | Digits: 19
15 Fib 1237 number is 19740274219868223167 | Digits: 20
16 Fib 1237 number is 83621143489848422977 | Digits: 20
17 Fib 1237 number is 927372692193078999176 | Digits: 21
18 Fib 1237 number is 781774079430987230203437 | Digits: 24
19 Fib 1237 number is 1264937032042997393488322 | Digits: 25
20 Fib 1237 number is 19134702400093278081449423917 | Digits: 29
21 Fib 1237 number is 1983924214061919432247806074196061 | Digits: 34
22 Fib 1237 number is 8404037832974134882743767626780173 | Digits: 34
23 Fib 1237 number is 162926777992448823780908130212788963731840407743629812913410 | Digits: 60
推荐阅读
- android - Android 编程返回按钮
- javascript - 从 php 文件运行 .innerHTML 以更改 HTML 元素
- http - set-cookie 标头未在 Edge 中设置 cookie
- rebol - Red 或 Rebol:如何将“test/a”转换为 [test/a]
- php - node.js 等效于 PHP if-else 显示 html 内容
- java - JLayeredPane 图像未显示
- docker - docker run $PATH 问题与 minikube / kubernetes
- python - Python:遍历数据集以将值传递到字典的最佳方法是什么?
- css - 在它的容器中居中图像
- command-prompt - 表格脚本,提示输入电子邮件地址以将表格作为 pdf 发送