我需要生成0(包含)到n(包含)范围内任意大的随机整数。我最初的想法是调用nextDouble并乘以n,但一旦n大于253,结果将不再是均匀分布的。

BigInteger具有以下构造函数:

public BigInteger(int numBits, Random rnd)

Constructs a randomly generated BigInteger, uniformly distributed over the range 0 to (2numBits - 1), inclusive.

怎样才能得到0-n范围内的随机值,其中n不是2的幂?

使用循环:

BigInteger randomNumber;

do {

randomNumber = new BigInteger(upperLimit.bitLength(), randomSource);

} while (randomNumber.compareTo(upperLimit) >= 0);

平均而言,这将需要少于两次迭代,并且选择将是一致的。

编辑:如果您的RNG很昂贵,您可以通过以下方式限制迭代次数:

int nlen = upperLimit.bitLength();

BigInteger nm1 = upperLimit.subtract(BigInteger.ONE);

BigInteger randomNumber, temp;

do {

temp = new BigInteger(nlen + 100, randomSource);

randomNumber = temp.mod(upperLimit);

} while (s.subtract(randomNumber).add(nm1).bitLength() >= nlen + 100);

// result is in 'randomNumber'

在这个版本中,循环被多次占用是非常不可能的(在2^100中不到一次机会,也就是说,远小于主机在接下来的一秒钟内自动着火的概率)。另一方面,mod()操作的计算代价很高,因此此版本可能比以前的版本慢,除非randomSource实例非常慢。

Java典型的RNGs到底有多慢?有没有常见的代码足够慢来证明这个额外的代码?

Java在EDOCX1 0中提供了密码安全的RNG,在我的PC上,它似乎每秒输出超过4兆字节的ALEA。这取决于Java实现(这里是Sun/Oracle Java 1.60Y26),体系结构(英特尔CORE2,2.4 GHz,64位模式)和操作系统(Linux)。

"s"在while条件应该是"temp",我想。

刚刚在带有OpenJDK 8和i7-6700 CPU@3.40GHz&215;8处理器的Linux系统上使用SecureRandom进行了一些性能测试。根据测试结果,第一个更简单的方法是速度的两到三倍。

下面的方法使用BigInteger(int numBits, Random rnd)构造函数,如果结果大于指定的n,则拒绝该结果。

public BigInteger nextRandomBigInteger(BigInteger n) {

Random rand = new Random();

BigInteger result = new BigInteger(n.bitLength(), rand);

while( result.compareTo(n) >= 0 ) {

result = new BigInteger(n.bitLength(), rand);

}

return result;

}

这样做的缺点是,构造函数被调用的次数未指定,但在最坏的情况下(n只是略大于2的幂),对构造函数的预期调用次数应该只有2次左右。

在最坏的情况下,平均呼叫数应该在2左右,而不是1.5:1呼叫(总是),+1(0.5 prob.),+1(0.5*0.5 prob.),+1(0.5*0.5*0.5 prob.)…这集中在2上,而不是1.5上。但这并没有造成那么大的差异。更直观的描述是:它执行20多个随机数代的概率只有百万分之一。

@Thomas Pornin:我想出了1.5,因为在最坏的情况下,50%的机会你只需要调用一次构造函数,50%的机会你需要第二次调用它,然后稳步减少你需要调用更多次的机会。这并没有考虑到实际上有100%的机会需要第一次调用构造函数,所以我的错误0.5是第一个术语。谢谢你的纠正。

最简单的方法(相当长的一段时间)是使用指定的构造函数生成一个具有正确位数的随机数(floor(log2 n) + 1),然后在大于n的情况下丢弃它。在最坏的情况下(例如范围[0,2n+1]中的一个数),平均丢弃的值不到创建值的一半。

@斯特里兰克:可能。我会让你从怀疑中获益,但我现在太困了,无法证实这一点:)

请把密码发过来好吗?

@费利佩米卡罗尼拉利:看比尔的回答…

@乔恩,对不起,我没有找到密码。它在你的电脑里吗?谢谢!

@费利佩米卡罗尼拉利:"看到比尔的答案"哪一点不清楚?蜥蜴比尔的答案,包含了一个完整的方法…

@乔恩·斯基特:你知道他只是在捣乱,对吧?

只需使用模块化缩减

new BigInteger(n.bitLength(), new SecureRandom()).mod(n)

以下是我如何在一个名为generic_biginteger的类中执行此操作,该类可通过以下方式获得:安迪·特纳的通用源代码网页

/**

* There are methods to get large random numbers. Indeed, there is a

* constructor for BigDecimal that allows for this, but only for uniform

* distributions over a binary power range.

* @param a_Random

* @param upperLimit

* @return a random integer as a BigInteger between 0 and upperLimit

* inclusive

*/

public static BigInteger getRandom(

Generic_Number a_Generic_Number,

BigInteger upperLimit) {

// Special cases

if (upperLimit.compareTo(BigInteger.ZERO) == 0) {

return BigInteger.ZERO;

}

String upperLimit_String = upperLimit.toString();

int upperLimitStringLength = upperLimit_String.length();

Random[] random = a_Generic_Number.get_RandomArrayMinLength(

upperLimitStringLength);

if (upperLimit.compareTo(BigInteger.ONE) == 0) {

if (random[0].nextBoolean()) {

return BigInteger.ONE;

} else {

return BigInteger.ZERO;

}

}

int startIndex = 0;

int endIndex = 1;

String result_String ="";

int digit;

int upperLimitDigit;

int i;

// Take care not to assign any digit that will result in a number larger

// upperLimit

for (i = 0; i < upperLimitStringLength; i ++){

upperLimitDigit = new Integer(

upperLimit_String.substring(startIndex,endIndex));

startIndex ++;

endIndex ++;

digit = random[i].nextInt(upperLimitDigit + 1);

if (digit != upperLimitDigit){

break;

}

result_String += digit;

}

// Once something smaller than upperLimit guaranteed, assign any digit

// between zero and nine inclusive

for (i = i + 1; i < upperLimitStringLength; i ++) {

digit = random[i].nextInt(10);

result_String += digit;

}

// Tidy values starting with zero(s)

while (result_String.startsWith("0")) {

if (result_String.length() > 1) {

result_String = result_String.substring(1);

} else {

break;

}

}

BigInteger result = new BigInteger(result_String);

return result;

}

为什么不先构造一个随机的biginteger,然后从中构造一个bigdecimal呢?在bigdecimal中有一个构造函数:public BigDecimal(BigInteger unscaledVal, int scale)似乎与此相关,不是吗?给它一个随机的biginteger和一个随机的scale int,你就会得到一个随机的bigdecimal。不?

随机比例在这里听起来是个坏主意。

将这个F代码编译成一个dll,您也可以在C/vb.net程序中引用它。

type BigIntegerRandom() =

static let internalRandom = new Random()

/// Returns a BigInteger random number of the specified number of bytes.

static member RandomBigInteger(numBytes:int, rand:Random) =

let r = if rand=null then internalRandom else rand

let bytes : byte[] = Array.zeroCreate (numBytes+1)

r.NextBytes(bytes)

bytes.[numBytes]

bigint bytes

/// Returns a BigInteger random number from 0 (inclusive) to max (exclusive).

static member RandomBigInteger(max:bigint, rand:Random) =

let rec getNumBytesInRange num bytes = if max < num then bytes else getNumBytesInRange (num * 256I) bytes+1

let bytesNeeded = getNumBytesInRange 256I 1

BigIntegerRandom.RandomBigInteger(bytesNeeded, rand) % max

/// Returns a BigInteger random number from min (inclusive) to max (exclusive).

static member RandomBigInteger(min:bigint, max:bigint, rand:Random) =

BigIntegerRandom.RandomBigInteger(max - min, rand) + min

问题是问JAVA

integer java 随机_如何在Java中生成随机BigInteger值?相关推荐

  1. python实现随机抽取答题_如何在python中实现随机选择

    这篇文章主要介绍了如何在python中实现随机选择,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 想从一个序列中随机抽取若干元素,或者想生成几个随机 ...

  2. 如何在C中生成随机int?

    是否有在C中生成随机int数的函数? 或者我必须使用第三方库吗? #1楼 让我们来看看. 首先,我们使用srand()函数为随机化器播种. 基本上,计算机可以根据提供给srand()的数字生成随机数. ...

  3. 中boxplot函数的参数设置_如何在Python中生成图形和图表

    在本章中,我们将学习如何在Python中生成图形和图表,同时将使用函数和面向对象的方法来可视化数据. Python中常用的一些可视化数据包括以下几种. Matplotlib. Seaborn. ggp ...

  4. java 联合_如何在java中进行联合,相交,区分和反向数据

    我想在Java中有联合,相交,差异和反向操作. 首先我有2个ArrayList< Integer> a = [0,2,4,5,6,8,10] b = [5,6,7,8,9,10] 一个工会 ...

  5. cmd中加载java源文件_如何在cmd中编译和运行java源文件

    如何在cmd中编译和运行java源文件 首先写一个名为HelloWorld.java的java源文件,存储在如C:/java/src的地址,我们再假设待会要存储的位置是C:/java/bin,则我们做 ...

  6. java 运费_如何在Java中创建运费成本计算器

    我正在创建计算器来计算运费.代码是这样的:如何在Java中创建运费成本计算器 class ShippingCalc { public static void main(String[] args) { ...

  7. java 二叉查找树_如何在Java中实现二叉搜索树( binary search tree)?

    二叉搜索树或BST是一种流行的数据结构,用于保持元素的顺序.二叉搜索树是二叉树,其中左子节点的值小于或等于父节点,右子节点的值大于或等于父节点.由于它是二叉树,它只能有0,1或2个子节点.二叉搜索树之 ...

  8. amd cpu不能在cmd环境下运行java代码_如何在Windows10中配置java的JDK环境

    今天给大家分享一下如何配置java的JDK环境.操作步骤如下: 1.下载好 jdk 的安装文件,我下载的是 jdk-10.0.1_windows-x64_bin.exe 这个版本的安装文件: 2.使用 ...

  9. python词云自定义形状_如何在Python中生成任何形状的词云

    作者 | Julia Kho 编辑| 代码医生团队 在本文中,我们将探讨如何在python中以您想要的任何形状生成文字云.我们将通过一个示例来说明如何在房屋的自定义形状中创建简单的文字云,如上图所示. ...

  10. Python办公自动化实战 09 | Python-docx库:Python与Word的完美结合_ 如何在Word中生成表格?把Python办公自动化进行到底

    一.专题内容简介 本小节主要演示了怎么向Word文档中创建表格并插入数据,并且对表格格式做个性化的设定. 二.专题案例效果 三.专题内容 3.1 创建表格并赋值 在使用Python-docx包对表格进 ...

最新文章

  1. 服务器购买是有无系统,买服务器含不含操作系统
  2. BZOJ2131 免费的馅饼【线段树优化DP】
  3. 【转】无法登陆SQL server 服务器的解决办法
  4. iOS-UICollectionView
  5. 安卓使用JNI-NDK
  6. 休眠事实:如何“断言” SQL语句计数
  7. node中定时器, process.nextTick(), setImediate()的区别与联系
  8. eclipse 调试nodejs 发生Failed to connect to standalone V8 VM错误的解决方案
  9. python 数据文件上传到ftp服务器
  10. java学习第123天,p750-761(05/23)干得漂亮
  11. Google浏览器拖拽安装扩展程序报错
  12. 常用软件分类 精选列表(一)
  13. 测试网页版淘宝购物车
  14. 2019秋招|从春招到秋招,Java岗经验总结(收获AT)
  15. 使用 kickstart 半自动化安装CentOS系统 利用PXE实现自动化安装centos系统
  16. 对于TextView中设置艺术字体
  17. 数据结构习题集之魔王语言解释
  18. 35个电子商务购物网站界面设计欣赏
  19. html manifest 不支持,如何让网站用上HTML5 Manifest
  20. 诊断功能第一讲-诊断基础知识

热门文章

  1. debian关闭开机自动启动时候的gui
  2. leetcode 1137 python
  3. 什么叫做java程序中的继承_【Java】基础16:什么叫继承?
  4. 今晚直播丨Oracle数据库之Object的Access方法和结合方法
  5. 直播丨国产最强音:HTAP融合型分布式数据库EsgynDB架构详解
  6. 解读年度数据库PostgreSQL:如何处理并发控制(一)
  7. DBA 14条职业选择路线,你适合哪种?
  8. 万字通俗讲解何为复杂度
  9. 在Spark Scala/Java应用中调用Python脚本,会么?
  10. 云小课|CDN第5课 CDN入门之—我的网站可以用CDN加速吗?