生成一定数量的数字的随机数

Generate random number of certain amount of digits

嗨,

我有一个非常基本的问题是:

如何在 Swift 中创建一个 20 位无浮点数无负数(基本上是 Int)的随机数?

谢谢大家的回答XD

这里有一些伪代码,可以执行您想要的操作。

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,因此您也应该防止出现这种情况。

第 1 步

首先我们需要Int的扩展来生成一个范围内的随机数。

extension Int {
    init(_ range: Range<Int> ) {
        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

这是 UInt64 中的 18 位十进制数字:

(Swift 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))

您可以创建一个字符串数字,然后将该数字转换为您需要的数字。

func generateRandomDigits(_ digitNumber: Int) -> String {
    var number = ""
    for i in 0..<digitNumber {
        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

Swift 3 appzyourlifz 的回答更新为 Swift 3

第 1 步:

extension Int {
init(_ range: Range<Int> ) {
    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 

Swift Unome 的验证响应的 4 版本加上:

  • 防止溢出和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
} 

Swift 5:简单的解决方案

func random(digits:Int) -> String {
    var number = String()
    for _ in 1...digits {
       number += "\(Int.random(in: 1...9))"
    }
    return number
}

print(random(digits: 1)) //3
print(random(digits: 2)) //59
print(random(digits: 3)) //926

注意它会return值在String,如果你需要Int值那么你可以这样做

let number = Int(random(digits: 1)) ?? 0