Generate random number of certain amount of digits

后端 未结 7 1855
不知归路
不知归路 2021-01-18 10:51

Hy,

I have a very Basic Question which is :

How can i create a random number with 20 digits no floats no negatives (basically an Int) in Swift ?

Than

相关标签:
7条回答
  • 2021-01-18 11:23

    Swift 3 appzyourlifz's answer updated to Swift 3

    Step 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)
        }
    }
    

    Step 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)))
    }
    

    Usage:

    randomNumberWith(digits:4) // 2271
    randomNumberWith(digits:8) // 65273410 
    
    0 讨论(0)
  • 2021-01-18 11:29

    Swift 5: Simple Solution

    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
    

    Note It will return value in String, if you need Int value then you can do like this

    let number = Int(random(digits: 1)) ?? 0
    
    0 讨论(0)
  • 2021-01-18 11:33

    Here is 18 decimal digits in a UInt64:

    (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.
    

    16 decimal digits with leading digit 1..9 in a UInt64:

    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))
    
    0 讨论(0)
  • 2021-01-18 11:34

    Here is some pseudocode that should do what you want.

    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
    }
    

    Its pretty simple. You generate 20 random numbers, and multiply them by the respective tens, hundredths, thousands... place that they should be on. This way you will guarantee a number of the correct size, but will randomly generate the number that will be used in each place.

    Update

    As said in the comments you will most likely get an overflow exception with a number this long, so you'll have to be creative in how you'd like to store the number (String, ect...) but I merely wanted to show you a simple way to generate a number with a guaranteed digit length. Also, given the current code there is a small chance your leading number could be 0 so you should protect against that as well.

    0 讨论(0)
  • 2021-01-18 11:39

    you can create a string number then convert the number to your required number.

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

    for 20 digit you can use Double instead of Int

    0 讨论(0)
  • Swift 4 version of Unome's validate response plus :

    • Guard it against overflow and 0 digit number

    • Adding support for Linux's device because "arc4random*" functions don't exit

    With linux device don't forgot to do

    #if os(Linux)
        srandom(UInt32(time(nil)))
    #endif
    

    only once before calling random.

    /// 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
    } 
    
    0 讨论(0)
提交回复
热议问题