ios Swift:寻找与Java';具有相同输出的s Random()PRNG

ios Swift:寻找与Java';具有相同输出的s Random()PRNG,java,ios,swift,compatibility,prng,Java,Ios,Swift,Compatibility,Prng,这是我的delimna: 我正在编写一个应用程序,它需要精确地再现一个用Java编写的游戏的PRNG输出,该游戏使用Java random()和给定的种子来创建它的所有初始游戏“世界”数据 我面临的问题是,当给定完全相同的种子时,Java的random()和ios Swift原生PRNG不会生成相同的值 以下是我的测试用例: 在所有情况下,都使用相同的“种子”,公式适用于0到9之间的随机整数 在Java中: import java.util.Random; long seed = 9872349

这是我的delimna: 我正在编写一个应用程序,它需要精确地再现一个用Java编写的游戏的PRNG输出,该游戏使用Java random()和给定的种子来创建它的所有初始游戏“世界”数据

我面临的问题是,当给定完全相同的种子时,Java的random()和ios Swift原生PRNG不会生成相同的值

以下是我的测试用例: 在所有情况下,都使用相同的“种子”,公式适用于0到9之间的随机整数

在Java中:

import java.util.Random;
long seed = 987234904;
Random rnd = new Random(seed);
int result = rnd.nextInt(10);
Java random()'结果'=0

在ios Swift中-使用srand48()/drand48():

ios Swift drand48()“结果”=7

在ios Swift中-使用rand_r():

ios Swift rand_r()结果=4

考虑到这一点,是否有一个ios Swift | Objective-C | C++代码snippit |库可用,它的功能和输出与Java版本的random()完全相同

不,这是不可能的(最有可能的),因为random的实现甚至不需要在不同的版本和系统中保持不变,您必须实现自己的random算法才能确保。或者你可以生成一个序列,保存它,然后以某种方式将它传输到另一个设备,但这要复杂得多

请看link中的示例部分,该部分给出了一个算法,并指出这可能对两种不同的机器有用:

static unsigned long next = 1;

/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}

void mysrand(unsigned seed) {
    next = seed;
}
在iOS 9和OS X 10.11中,您只需将其转换为首选语言

,它提供了一套确定性PRNG,其主要原理之一是,您可以在多台设备上或在多人游戏的服务器和客户端之间复制随机序列。(有关更多原理和其他有趣的内容,请参阅。)


特别是,使用Knuth标准,因此应与
java.util.Random
(当然,当使用相同的48位种子初始化时)兼容。

好的-以下是解决方法:

我在苹果论坛上问了同样的问题,一个叫“ahltorp”的好人分享了一个c函数,他们一直在用这个函数做同样的事情。它是swift兼容的,我已经用我的模拟对它进行了测试,这是一个完美的数据匹配

C函数的Github位置:

请举例说明如何使用它

var插入:UInt64=987234904
java_random_setseed(插入和插入)
var result=java\u random\u nextint\n(&插图,10)
打印(结果)
结果=0:-)

苹果论坛讨论的链接:

Ah-但实际上应该是可能的-正如Java自己的文档中所定义的那样。:-)<代码>此类的实例用于生成伪随机数流。该类使用48位种子,该种子使用线性同余公式进行修改。(参见Donald Knuth,《计算机编程艺术》,第2卷,第3.2.1节。)@dano仅仅因为这两种方法使用相同的公式/算法并不意味着它们产生相同的数字,一个公式通常有多个独立选择的参数。考虑我所发布的函数,假设两种方法都使用这样的算法,使用相同的确切数字的可能性微乎其微;谢谢你的信息!我安装了Xcode 7 Beta版,并设法为此搭建了一个游乐场——但遗憾的是,数字错了
import-UIKit-import-GameplayKit-if#available(iOS 9,*){let-seed:UInt64=987234904-let-random=gklinearconruentialrandomSource(seed:seed)let-result=random.nextIntWithUpperBound(10)//应该是0到9之间的随机整数(总共10种可能性)
这给出了6的“结果”。测试用例应该是“0”。:-?
import UIKit
var seed: UInt32 = 987234904
var result = Int(Float(rand_r(&seed))/Float(INT32_MAX)*10)
static unsigned long next = 1;

/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}

void mysrand(unsigned seed) {
    next = seed;
}