HY,
我有一个非常基本的问题:
如何在Swift中创建一个20位数字的随机数,没有浮点数,没有负数(基本上是Int)?
感谢所有答案XD
前导数字可以为0吗?
是的,那不会成熟
以下是一些针对64位随机整数的解决方案:stackoverflow.com/questions/26549830/,但请注意,UInt64不足以容纳具有20个十进制数字的任意整数(10 ^ 20> 2 ^ 64)。
可以用64位表示的最大数字是:18446744073709551616,这是不够的。 20个十进制数字将需要67位。 您如何建议保留该号码?
@HuRiXD您真的想要一个20位数字吗? 还是随机抽取的一个示例数字使计算机科学家感到紧张?
纠错是随机的20会很好,但是如果14或18使它更容易,如果也可以
步骤1
首先,我们需要扩展Int来生成一定范围内的随机数。
extension Int {
init(_ range: Range ) {
let delta = range.startIndex < 0 ? abs(range.startIndex) : 0
let min = UInt32(range.startIndex + delta)
let max = UInt32(range.endIndex + delta)
self.init(Int(min + arc4random_uniform(max - min)) - delta)
}
}
可以这样使用:
Int(0...9) // 4 or 1 or 1...
Int(10...99) // 90 or 33 or 11
Int(100...999) // 200 or 333 or 893
第2步
现在,我们需要一个函数,该函数接收请求的位数,计算随机数的范围,最后调用新的Int初始化程序。
func random(digits:Int) -> Int {
let min = Int(pow(Double(10), Double(digits-1))) - 1
let max = Int(pow(Double(10), Double(digits))) - 1
return Int(min...max)
}
测试
random(1) // 8
random(2) // 12
random(3) // 829
random(4) // 2374
喜欢扩展的想法! +1
实际上,在这里,我仅使用扩展名来生成一定范围内的随机数。但是您是对的,我们可以将random函数转换为UInt的扩展。
您将如何表示号码36893488147419103232? (需要超过64位,但仍然只有20个十进制数字。
同样,这不能使用20位数字。另请注意,如果范围包括负数,则UInt32(..)计算可能会在64位平台上溢出(此问题不是这种情况)。尝试let rnd = Int(Int.min + 10 ..< Int.max - 10)(它崩溃)。这是产生任意整数范围内随机数的安全方法:stackoverflow.com/questions/31391577/。
@MartinR:你是对的。
在Swift 4中,出现错误"无法使用类型为(CountableClosedRange )的参数列表调用Int类型的初始化程序"
这是一些应该执行所需操作的伪代码。
generateRandomNumber(20)
func generateRandomNumber(int numDigits){
var place = 1
var finalNumber = 0;
for(int i = 0; i < numDigits; i++){
place *= 10
var randomNumber = arc4random_uniform(10)
finalNumber += randomNumber * place
}
return finalNumber
}
非常简单。您生成20个随机数,然后将它们乘以相应的数十,百分之一,几千……应该放在的位置。这样,您将保证一定数量的正确大小,但会随机生成将在每个位置使用的数字。
更新资料
如评论中所述,您很可能会遇到一个如此长的数字溢出异常,因此您必须在如何存储数字(字符串等)方面很有创意,但我只想向您展示一种生成具有保证位数长度的数字的简单方法。同样,考虑到当前代码,您的前导数字很有可能为0,因此您也应对此加以防范。
这可能会因Swift中的溢出异常而中止。
可能是正确的...在这种情况下,将其存储在类似UUID的字符串中,并在需要时将其解析回数字。
解析回一个数字在哪里?变成uint128_t?
好点@zaph。我不确定为什么他需要一个20位数的数字。但是,也许这个问题更适合于生成带有一定位数的数字,而20是一个不寻常的随机数。标题询问如何生成数字,帖子是神秘数字20出现的位置。
您可以创建一个字符串号,然后将该数字转换为所需的数字。
func generateRandomDigits(_ digitNumber: Int) -> String {
var number =""
for i in 0..
var randomNumber = arc4random_uniform(10)
while randomNumber == 0 && i == 0 {
randomNumber = arc4random_uniform(10)
}
number +="\(randomNumber)"
}
return number
}
print(Int(generateRandomDigits(3)))
对于20位数字,您可以使用Double而不是Int
Unome的Swift 4版本的validate响应以及:
防止溢出和0位数字
添加对Linux设备的支持,因为" arc4random *"功能不会退出
使用linux设备不要忘记做
#if os(Linux)
srandom(UInt32(time(nil)))
#endif
在随机调用之前只有一次。
/// This function generate a random number of type Int with the given digits number
///
/// - Parameter digit: the number of digit
/// - Returns: the ramdom generate number or nil if wrong parameter
func randomNumber(with digit: Int) -> Int? {
guard 0 < digit, digit < 20 else { // 0 digit number don't exist and 20 digit Int are to big
return nil
}
/// The final ramdom generate Int
var finalNumber : Int = 0;
for i in 1...digit {
/// The new generated number which will be add to the final number
var randomOperator : Int = 0
repeat {
#if os(Linux)
randomOperator = Int(random() % 9) * Int(powf(10, Float(i - 1)))
#else
randomOperator = Int(arc4random_uniform(9)) * Int(powf(10, Float(i - 1)))
#endif
} while Double(randomOperator + finalNumber) > Double(Int.max) // Verification to be sure to don't overflow Int max size
finalNumber += randomOperator
}
return finalNumber
}
迅捷3
appzyourlifz的答案更新为Swift 3
步骤1:
extension Int {
init(_ range: Range ) {
let delta = range.lowerBound < 0 ? abs(range.lowerBound) : 0
let min = UInt32(range.lowerBound + delta)
let max = UInt32(range.upperBound + delta)
self.init(Int(min + arc4random_uniform(max - min)) - delta)
}
}
第2步:
func randomNumberWith(digits:Int) -> Int {
let min = Int(pow(Double(10), Double(digits-1))) - 1
let max = Int(pow(Double(10), Double(digits))) - 1
return Int(Range(uncheckedBounds: (min, max)))
}
用法:
randomNumberWith(digits:4) // 2271
randomNumberWith(digits:8) // 65273410
这是UInt64中的18个十进制数字:
(快速3)
let sz: UInt32 = 1000000000
let ms: UInt64 = UInt64(arc4random_uniform(sz))
let ls: UInt64 = UInt64(arc4random_uniform(sz))
let digits: UInt64 = ms * UInt64(sz) + ls
print(String(format:"18 digits: %018llu", digits)) // Print with leading 0s.
UInt64中带前导数字1..9的16个十进制数字:
let sz: UInt64 = 100000000
let ld: UInt64 = UInt64(arc4random_uniform(9)+1)
let ms: UInt64 = UInt64(arc4random_uniform(UInt32(sz/10)))
let ls: UInt64 = UInt64(arc4random_uniform(UInt32(sz)))
let digits: UInt64 = ld * (sz*sz/10) + (ms * sz) + ls
print(String(format:"16 digits: %llu", digits))
谢谢您的解决方案。如何获得16位十进制数字?
已经使用过,但有时会返回15位数字...
将答案更新为16位数字,其中前导数字必须为1-9。