I want to get a random element from 0 to a huge number (2^31).
I tried creating an Array from such a Range (so I can use Swift's Array.randomElement), as done here:
let myArray: [Int64] = [Int64](0...4294967292)
Which compiles, but crashes with:
MyPoject(1569,0x100cc2f40) malloc: can't allocate region mach_vm_map(size=34359738368) failed (error code=3) MyProject(1569,0x100cc2f40) malloc: set a breakpoint in malloc_error_break to debug
Of course, I can write a custom function to create the array, but that smells, especially because the array will be the exact same every time.
Does Swift provide a better solution?
The error message
malloc: can't allocate region mach_vm_map(size=34359738368)
tells that the runtime could not allocate 32GB memory – that is what an array of 4294967292 64-bit integers would require at
let myArray: [Int64] = [Int64](0...4294967292)
But there is no need to create an array for that purpose. As of Swift 4.2 you can simply call
let rnd = Int64.random(in: 0...4294967292)
// or
let rnd = Int64.random(in: 0..<4294967293)
using one of the
static func random(in range: ClosedRange<Self>) -> Self
static func random(in range: Range<Self>) -> Self
methods of the FixedWidthInteger protocol.
Finally note that 4294967292 is not 2^31 = 2147483648 – if the intention is to create a random number in the range from 0 (inclusive) to 2^31 (exclusive) then
let rnd = Int32.random(in: 0...Int32.max)
would to the trick.
ClosedRange also has a randomElement method in Swift 4.2:
print((0...4294967292).randomElement()!)
Note that you said you want a random number between 0 and 2^31, but you used 1...4294967292 instead of 0...4294967292 in your example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With