Swift中生成正负区间随机数用于X轴定位的问题求助
我来帮你解决这个正负区间随机数的问题!你用arc4random和arc4random_uniform没成功,大概率是没处理好范围转换和类型兼容的细节,下面给你几个实用的实现方案,不管是整数还是浮点数都能搞定:
对称区间(比如 [-N, N])
如果你需要的是对称的整数范围,比如 -5 到 5,可以先让arc4random_uniform生成一个覆盖两倍范围+1的无符号整数,再减去基准值N,这样就能得到对称的正负区间:
Objective-C 代码:
int targetRange = 5; // 生成 [-5, 5] 之间的随机整数 int randomInt = arc4random_uniform(2 * targetRange + 1) - targetRange;
Swift 代码:
let targetRange = 5 // 生成 [-5, 5] 之间的随机整数 let randomInt = Int(arc4random_uniform(UInt32(2 * targetRange + 1))) - targetRange
原理:arc4random_uniform(11)会生成0~10的整数,减去5后就刚好覆盖-5~5的区间。
非对称区间(比如 [-3, 7])
如果是不对称的正负区间,先算出区间的总长度,用arc4random_uniform生成对应长度的随机数,再加上区间的最小值即可:
Objective-C 代码:
int minVal = -3; int maxVal = 7; // 生成 [-3, 7] 之间的随机整数 int randomInt = minVal + arc4random_uniform(maxVal - minVal + 1);
Swift 代码:
let minVal = -3 let maxVal = 7 // 生成 [-3, 7] 之间的随机整数 let randomInt = minVal + Int(arc4random_uniform(UInt32(maxVal - minVal + 1)))
原理:区间总长度是7 - (-3) + 1 = 11,arc4random_uniform(11)生成0~10,加上-3后就得到-3~7的范围。
如果需要的是带小数的随机数(比如动画中对象的X轴位置),可以把arc4random的结果转换成0~1的浮点数,再缩放并偏移到目标正负区间:
Objective-C 代码:
CGFloat targetRange = 2.5; // 目标区间是 [-2.5, 2.5] // 生成 [-2.5, 2.5] 之间的随机浮点数 CGFloat randomFloat = ((CGFloat)arc4random() / UINT32_MAX) * 2 * targetRange - targetRange;
Swift 代码:
let targetRange: CGFloat = 2.5 // 目标区间是 [-2.5, 2.5] // 生成 [-2.5, 2.5] 之间的随机浮点数 let randomFloat = (CGFloat(arc4random()) / CGFloat(UINT32_MAX)) * 2 * targetRange - targetRange;
原理:(CGFloat)arc4random() / UINT32_MAX会得到0~1的浮点数,乘以2*targetRange得到0~5,再减去targetRange就变成-2.5~2.5。
很多人用arc4random时会直接做减法(比如arc4random() - 5),但arc4random返回的是无符号整数(UInt32),当结果为负数时会溢出成超大的正数,导致逻辑出错。所以一定要先转换成有符号类型,或者用arc4random_uniform控制范围后再偏移。
内容的提问来源于stack exchange,提问作者Pastor Moreno

