Swiftで、0から1の間のランダムなフロートを取得しようとしていますが、型変換を機能させることができないようです。
func randomCGFloat() -> CGFloat {
return CGFloat(arc4random()) / UINT32_MAX
}
「CGFloat」は「UInt8」エラーに変換できません
Xcode6を実行しています。
Swiftで、0から1の間のランダムなフロートを取得しようとしていますが、型変換を機能させることができないようです。
func randomCGFloat() -> CGFloat {
return CGFloat(arc4random()) / UINT32_MAX
}
「CGFloat」は「UInt8」エラーに変換できません
Xcode6を実行しています。
回答:
除数をフロートとして初期化してみてください。
CGFloat(Float(arc4random()) / Float(UINT32_MAX))
Float
–ただCGFloat(arc4random()) / CGFloat(UInt32.max)
。
これは 、Int、Double、Float、CGFloatの乱数の拡張です。
Swift 3&4&5構文
import Foundation
import CoreGraphics
// MARK: Int Extension
public extension Int {
/// Returns a random Int point number between 0 and Int.max.
static var random: Int {
return Int.random(n: Int.max)
}
/// Random integer between 0 and n-1.
///
/// - Parameter n: Interval max
/// - Returns: Returns a random Int point number between 0 and n max
static func random(n: Int) -> Int {
return Int(arc4random_uniform(UInt32(n)))
}
/// Random integer between min and max
///
/// - Parameters:
/// - min: Interval minimun
/// - max: Interval max
/// - Returns: Returns a random Int point number between 0 and n max
static func random(min: Int, max: Int) -> Int {
return Int.random(n: max - min + 1) + min
}
}
// MARK: Double Extension
public extension Double {
/// Returns a random floating point number between 0.0 and 1.0, inclusive.
static var random: Double {
return Double(arc4random()) / 0xFFFFFFFF
}
/// Random double between 0 and n-1.
///
/// - Parameter n: Interval max
/// - Returns: Returns a random double point number between 0 and n max
static func random(min: Double, max: Double) -> Double {
return Double.random * (max - min) + min
}
}
// MARK: Float Extension
public extension Float {
/// Returns a random floating point number between 0.0 and 1.0, inclusive.
static var random: Float {
return Float(arc4random()) / 0xFFFFFFFF
}
/// Random float between 0 and n-1.
///
/// - Parameter n: Interval max
/// - Returns: Returns a random float point number between 0 and n max
static func random(min: Float, max: Float) -> Float {
return Float.random * (max - min) + min
}
}
// MARK: CGFloat Extension
public extension CGFloat {
/// Randomly returns either 1.0 or -1.0.
static var randomSign: CGFloat {
return (arc4random_uniform(2) == 0) ? 1.0 : -1.0
}
/// Returns a random floating point number between 0.0 and 1.0, inclusive.
static var random: CGFloat {
return CGFloat(Float.random)
}
/// Random CGFloat between 0 and n-1.
///
/// - Parameter n: Interval max
/// - Returns: Returns a random CGFloat point number between 0 and n max
static func random(min: CGFloat, max: CGFloat) -> CGFloat {
return CGFloat.random * (max - min) + min
}
}
使用する :
let randomNumDouble = Double.random(min: 0.00, max: 23.50)
let randomNumInt = Int.random(min: 56, max: 992)
let randomNumFloat = Float.random(min: 6.98, max: 923.09)
let randomNumCGFloat = CGFloat.random(min: 6.98, max: 923.09)
return Float(arc4random()) / 0xFFFFFFFF
警告が表示されるようになりました'4294967295' is not exactly representable as 'Float'; it becomes '4294967296'
。その警告を解決する方法はありますか?Float(UInt32.max)
代わりに割り算を考えています。
Swift3のSandyChapmanの回答を更新します。
extension ClosedRange where Bound : FloatingPoint {
public func random() -> Bound {
let range = self.upperBound - self.lowerBound
let randomValue = (Bound(arc4random_uniform(UINT32_MAX)) / Bound(UINT32_MAX)) * range + self.lowerBound
return randomValue
}
}
今、あなたはのようなものを言うことができます(-1.0...1.0).random()
。
編集私は今日思う(Swift 4)私は次のようなものを書くだろう:
extension ClosedRange where Bound : FloatingPoint {
public func random() -> Bound {
let max = UInt32.max
return
Bound(arc4random_uniform(max)) /
Bound(max) *
(upperBound - lowerBound) +
lowerBound
}
}
注Swift4.2では、ネイティブの乱数生成が導入されており、これはすべて意味がありません。
ここで、フレームワークはSwiftで乱数データを生成するのに適しています:https: //github.com/thellimist/SwiftRandom/blob/master/SwiftRandom/Randoms.swift
public extension Int {
/// SwiftRandom extension
public static func random(lower: Int = 0, _ upper: Int = 100) -> Int {
return lower + Int(arc4random_uniform(UInt32(upper - lower + 1)))
}
}
public extension Double {
/// SwiftRandom extension
public static func random(lower: Double = 0, _ upper: Double = 100) -> Double {
return (Double(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
}
}
public extension Float {
/// SwiftRandom extension
public static func random(lower: Float = 0, _ upper: Float = 100) -> Float {
return (Float(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower
}
}
public extension CGFloat {
/// SwiftRandom extension
public static func random(lower: CGFloat = 0, _ upper: CGFloat = 1) -> CGFloat {
return CGFloat(Float(arc4random()) / Float(UINT32_MAX)) * (upper - lower) + lower
}
}
Generic iOS device
。0xffffffffはInt内に収まりません。代わりにこれを試してくださいCGFloat(UInt32.max)
以下は、IntervalType
これを行うためのタイプの拡張です。
extension IntervalType {
public func random() -> Bound {
let range = (self.end as! Double) - (self.start as! Double)
let randomValue = (Double(arc4random_uniform(UINT32_MAX)) / Double(UINT32_MAX)) * range + (self.start as! Double)
return randomValue as! Bound
}
}
この拡張機能を使用すると、間隔構文を使用して間隔を生成し、その間隔でランダムな値を取得できます。
(0.0...1.0).random()
添加
Int
sについても同じことを行う場合は、CollectionType
プロトコルで次の拡張機能を使用できます。
extension CollectionType {
public func random() -> Self._Element {
if let startIndex = self.startIndex as? Int {
let start = UInt32(startIndex)
let end = UInt32(self.endIndex as! Int)
return self[Int(arc4random_uniform(end - start) + start) as! Self.Index]
}
var generator = self.generate()
var count = arc4random_uniform(UInt32(self.count as! Int))
while count > 0 {
generator.next()
count = count - 1
}
return generator.next() as! Self._Element
}
}
Int
sは使用しないでくださいIntervalType
。Range
代わりに使用します。CollectionType
タイプでこれを行う利点は、タイプDictionary
とArray
タイプに自動的に引き継がれることです。
例:
(0...10).random() // Ex: 6
["A", "B", "C"].random() // Ex: "B"
["X":1, "Y":2, "Z":3].random() // Ex: (.0: "Y", .1: 2)
.random()
に関する詳細で回答を更新しましたInt
Dictionary
Array
jmdukeが提案したことは、関数を少し変更するだけでPlaygroundで機能するようです。
func randomCGFloat() -> Float {
return Float(arc4random()) / Float(UInt32.max)
}
そして、迅速なドキュメントから、drewag:型変換が明示的でなければならない理由、ドキュメントの例は次のとおりです。
let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// pi equals 3.14159, and is inferred to be of type Double
YannickStephの回答に基づく
それはどの浮動小数点型、などのために働くようにするにはDouble
、Float
、CGFloat
、など、あなたがのために拡張することができますBinaryFloatingPoint
タイプ:
extension BinaryFloatingPoint {
/// Returns a random floating point number between 0.0 and 1.0, inclusive.
public static var random: Self {
return Self(arc4random()) / 0xFFFFFFFF
}
/// Random double between 0 and n-1.
///
/// - Parameter n: Interval max
/// - Returns: Returns a random double point number between 0 and n max
public static func random(min: Self, max: Self) -> Self {
return Self.random * (max - min) + min
}
}
Xcode:9.2、Swift 4
extension BinaryInteger {
static func rand(_ min: Self, _ max: Self) -> Self {
let _min = min
let difference = max+1 - _min
return Self(arc4random_uniform(UInt32(difference))) + _min
}
}
extension BinaryFloatingPoint {
private func toInt() -> Int {
// https://stackoverflow.com/q/49325962/4488252
if let value = self as? CGFloat {
return Int(value)
}
return Int(self)
}
static func rand(_ min: Self, _ max: Self, precision: Int) -> Self {
if precision == 0 {
let min = min.rounded(.down).toInt()
let max = max.rounded(.down).toInt()
return Self(Int.rand(min, max))
}
let delta = max - min
let maxFloatPart = Self(pow(10.0, Double(precision)))
let maxIntegerPart = (delta * maxFloatPart).rounded(.down).toInt()
let randomValue = Int.rand(0, maxIntegerPart)
let result = min + Self(randomValue)/maxFloatPart
return Self((result*maxFloatPart).toInt())/maxFloatPart
}
}
print("\(Int.rand(1, 20))")
print("\(Float.rand(5.231233, 44.5, precision: 3))")
print("\(Double.rand(5.231233, 44.5, precision: 4))")
print("\(CGFloat.rand(5.231233, 44.5, precision: 6))")
import Foundation
import CoreGraphics
func run() {
let min = 2.38945
let max = 2.39865
for _ in 0...100 {
let precision = Int.rand(0, 5)
print("Precision: \(precision)")
floatSample(min: Float(min), max: Float(max), precision: precision)
floatSample(min: Double(min), max: Double(max), precision: precision)
floatSample(min: CGFloat(min), max: CGFloat(max), precision: precision)
intSample(min: Int(1), max: Int(10000))
print("")
}
}
private func printResult<T: Comparable>(min: T, max: T, random: T) {
let result = "\(T.self) rand[\(min), \(max)] = \(random)"
print(result)
}
func floatSample<T: BinaryFloatingPoint>(min: T, max: T, precision: Int) {
printResult(min: min, max: max, random: T.rand(min, max, precision: precision))
}
func intSample<T: BinaryInteger>(min: T, max: T) {
printResult(min: min, max: max, random: T.rand(min, max))
}