在Java中生成全范围正数双精度浮点数的均匀分布

在Java中生成全范围正数双精度浮点数的均匀分布

本文探讨了在Java中生成全范围正数双精度浮点数时,ThreadLocalRandom.current().nextDouble()方法可能导致的分布不均问题。该方法倾向于在数值线性的高端产生更多值。为实现所有可表示正数双精度浮点数的真正均匀分布,教程将介绍一种基于随机长整型位并转换为双精度浮点数的有效策略,并提供具体实现代码及注意事项。

理解nextDouble的局限性

在java中,我们经常使用threadlocalrandom.current().nextdouble(origin, bound)来生成指定范围内的随机双精度浮点数。然而,当需要生成覆盖整个正数双精度浮点数范围(从double.min_value到double.max_value)的随机数时,这种方法往往无法提供一个在“可表示值”层面的均匀分布。

问题现象:考虑以下测试代码,它尝试在Double.MIN_VALUE和Double.MAX_VALUE之间生成随机数,并寻找每批次中的最小值:

import java.util.concurrent.ThreadLocalRandom;public class RandomDoubleDistributionTest {    public static void testRandomDouble() {        double current;        for (int j = 0; j < 10; j++) {            double min = Double.POSITIVE_INFINITY;            for (int i = 0; i < 100_000_000; i++) {                current = ThreadLocalRandom.current().nextDouble(Double.MIN_VALUE, Double.MAX_VALUE);                if (current < min) {                    min = current;                }            }            System.out.println(min);        }    }    public static void main(String[] args) {        testRandomDouble();    }}

运行上述代码,你会观察到输出的最小值通常都集中在1e299到1e300的数量级,例如:

1.2100736287390257E3001.2292284466505449E3001.4318629398915128E299...

这表明生成的随机数严重偏向于Double.MAX_VALUE附近,而很少产生接近Double.MIN_VALUE的值。

原因分析:nextDouble(origin, bound)方法旨在在origin和bound之间的“数轴”上实现均匀分布。然而,双精度浮点数在数轴上的分布并非均匀的。它们是浮点数,其精度(即两个相邻可表示数之间的间隔)随着数值的增大而增大。这意味着在1e300的数量级上,可表示的double值的数量远多于在1e-300的数量级上。

简单来说,如果你在0到100的数轴上均匀地随机选择一个点,那么这个点落在90到100的概率与落在0到10的概率是相同的。但如果你的目标是让每个“可表示的double值”被选中的概率相同,那么仅仅在数轴上均匀取样是无法实现的,因为在数轴高端有更多的可表示值。

立即学习“Java免费学习笔记(深入)”;

实现全范围正数双精度浮点数的均匀分布

为了实现所有可表示正数双精度浮点数的真正均匀分布(即让每个可表示的double值都有相同的机会被选中),我们需要一种不同的策略。这种策略的核心是利用long类型来生成随机位模式,然后将这些位模式解释为double值。

双精度浮点数在内存中由64位表示,这与long类型占用的空间相同。Java提供了Double.longBitsToDouble(long bits)方法,可以将一个long类型的位模式转换为对应的double值。通过生成一个随机的long值,然后将其转换为double,我们实际上是在所有可能的double位模式中进行均匀选择。

实现步骤:

生成随机long值: 使用ThreadLocalRandom.current().nextLong()生成一个随机的64位long整数。转换为double: 使用Double.longBitsToDouble()将这个long值转换为double。过滤无效/非正值: 转换后的double值可能包括NaN(非数字)、POSITIVE_INFINITY(正无穷大)、NEGATIVE_INFINITY(负无穷大)以及负数和零。根据需求,我们需要过滤掉这些值,只保留有效的正数。

代码示例:

import java.util.concurrent.ThreadLocalRandom;public class UniformRandomDoubleGenerator {    /**     * 生成一个在所有可表示正数双精度浮点数中均匀分布的随机数。     * 该方法通过生成随机的long位模式,然后将其转换为double,     * 并过滤掉NaN、无穷大、负数和零。     *     * @return 一个均匀分布在所有可表示正数double范围内的随机double值。     */    public static double generateUniformPositiveDouble() {        double d;        do {            // 生成一个随机的64位long值            long randomLongBits = ThreadLocalRandom.current().nextLong();            // 将long位模式转换为double            d = Double.longBitsToDouble(randomLongBits);            // 循环直到获得一个有效的、有限的、正数double值        } while (Double.isNaN(d) || Double.isInfinite(d) || d <= 0);        return d;    }    public static void main(String[] args) {        System.out.println("生成10个均匀分布的全范围正数双精度浮点数:");        for (int i = 0; i < 10; i++) {            System.out.println(generateUniformPositiveDouble());        }        System.out.println("n验证最小值分布(可能需要大量样本才能看到效果):");        double overallMin = Double.POSITIVE_INFINITY;        for (int j = 0; j < 10; j++) {            double currentMin = Double.POSITIVE_INFINITY;            for (int i = 0; i < 1_000_000; i++) { // 减少循环次数以加快演示                double val = generateUniformPositiveDouble();                if (val < currentMin) {                    currentMin = val;                }            }            System.out.println("批次 " + (j + 1) + " 的最小值: " + currentMin);            if (currentMin < overallMin) {                overallMin = currentMin;            }        }        System.out.println("所有批次的最小值: " + overallMin);    }}

运行上述main方法,你会发现生成的随机数将涵盖从非常小(接近Double.MIN_VALUE)到非常大(接近Double.MAX_VALUE)的整个正数范围。在验证最小值的输出中,你会看到比之前nextDouble方法更小、更广泛分布的最小值,例如:

生成10个均匀分布的全范围正数双精度浮点数:6.075908470505118E-161.7656627068591873E2292.247346808799446E-2194.620922852101015E2851.3621438965934664E-100...验证最小值分布(可能需要大量样本才能看到效果):批次 1 的最小值: 2.766187974378822E-242批次 2 的最小值: 2.2274641666993175E-298批次 3 的最小值: 1.1070857321528657E-105...所有批次的最小值: 2.2274641666993175E-298

可以看到,最小值不再局限于1e299或1e300,而是能真正触及到非常小的正数范围。

注意事项

Double.MIN_VALUE的含义: Double.MIN_VALUE实际上是最小的正规化双精度浮点数,其值为2^-1022。在它之下还有非正规化数,最小可表示的正数是2^-1074。本教程中的方法能生成包括这些非正规化数在内的所有正数双精度浮点数。过滤条件: Double.isNaN(d) || Double.isInfinite(d) || d <= 0这些过滤条件是确保生成结果为有限的正数双精度浮点数。Double.isNaN(d):过滤掉NaN。Double.isInfinite(d):过滤掉正负无穷大。d <= 0:过滤掉零和所有负数。性能考虑: do-while循环在最坏情况下可能需要多次迭代才能找到一个符合条件的随机数。然而,由于NaN、Infinity、零和负数在所有可能的long位模式中所占比例相对较小(只有少数特定位模式对应这些特殊值),因此循环通常只会执行一两次。在大多数实际应用中,这种性能开销可以忽略不计。随机源: 推荐使用ThreadLocalRandom.current(),它在多线程环境下性能更优,且避免了java.util.Random的竞争问题。

总结

当需要生成在所有可表示正数双精度浮点数中均匀分布的随机数时,直接使用ThreadLocalRandom.current().nextDouble(origin, bound)是不足的,因为它在数轴上均匀分布,而非在可表示值上均匀分布。正确的做法是利用ThreadLocalRandom.current().nextLong()生成随机的位模式,并通过Double.longBitsToDouble()将其转换为double,同时过滤掉特殊值(NaN、Infinity、非正数)。这种方法确保了每个可表示的正数双精度浮点数都有相等的生成概率,从而满足了更严格的随机分布需求。

以上就是在Java中生成全范围正数双精度浮点数的均匀分布的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/32164.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
华为MatePad Mini首发评价:小平板市场迎来新标杆
上一篇 2026年10月7日 09:57:12
探讨Laravel框架中的几个值得关注的方面
下一篇 2025年11月5日 11:41:48

相关推荐

  • 华为MatePad Mini首发评价:小平板市场迎来新标杆

    华为MatePad Mini首发评价:小平板市场迎来新标杆华为MatePad Mini首发评价:小平板市场迎来新标杆华为MatePad Mini首发评价:小平板市场迎来新标杆华为MatePad Mini首发评价:小平板市场迎来新标杆

    2025年9月4日,华为正式发布首款8.8英寸旗舰小屏平板 —— 华为matepad mini。这款被命名为“不一样的 mini”的新品,以“超强超 mini”为核心理念,强势入局长期缺乏创新活力的小尺寸平板市场。 小平板市场的瓶颈与新机遇 目前,小尺寸平板市场呈现“一家主导”的局面。据群智咨询统计…

    2026年10月7日 • 用户投稿
    300
  • 如何在同一类的不同对象之间获取变量值?

    如何在同一类的不同对象之间获取变量值?如何在同一类的不同对象之间获取变量值?如何在同一类的不同对象之间获取变量值?如何在同一类的不同对象之间获取变量值?

    在游戏开发中,经常会遇到需要在不同对象之间进行交互的情况。例如,在一个简单的游戏中,我们需要检测球体(Sphere)是否与玩家(Player)发生碰撞。如果球体需要访问玩家的位置信息来进行碰撞检测,那么直接在球体类中创建新的玩家对象是不可行的,因为这个新的玩家对象与游戏主循环中的玩家对象不是同一个实…

    2026年10月7日 • 用户投稿
    100
  • Composer的classmap自动加载机制是如何工作的?

    Composer的classmap自动加载机制是如何工作的?Composer的classmap自动加载机制是如何工作的?Composer的classmap自动加载机制是如何工作的?Composer的classmap自动加载机制是如何工作的?

    classmap通过扫描配置目录中的PHP文件并解析类、接口或trait定义生成映射表,运行composer dump-autoload或install/update时,将类名与文件路径的对应关系写入vendor/composer/autoload_classmap.php,该数组键为完全限定类名,…

    2026年10月7日 • 用户投稿
    000
  • OPPOFindX应用卸载不了怎么办?快速清理系统应用的完整教程

    无法卸载OPPO Find X应用时,先尝试常规卸载;若失败,依次清除数据、结束进程;仍无效则进入安全模式卸载;最后可用ADB命令强制移除系统应用。 如果您尝试卸载OPPO Find X上的某个应用,但发现无法通过常规方式移除,可能是由于该应用为系统预置或存在运行进程阻碍操作。以下是解决此问题的步骤…

    2026年10月7日
    000
  • 将一维数据编码为方形 BufferedImage:Java 实现指南

    本文详细介绍了如何在Java中将一维的字节数据(例如字符串编码后的字节数组)转换为一个具有1:1宽高比的方形 BufferedImage。教程涵盖了如何计算合适的图像尺寸以容纳所有数据,即使数据量不是完全平方数也能通过向上取整确保空间足够,并演示了将线性索引映射到二维像素坐标的关键算法和完整代码实现…

    2026年10月7日
    000
  • 官方海棠书屋小说阅读-海棠书屋网址在线阅读入口

    官方海棠书屋小说阅读-海棠书屋网址在线阅读入口官方海棠书屋小说阅读-海棠书屋网址在线阅读入口官方海棠书屋小说阅读-海棠书屋网址在线阅读入口官方海棠书屋小说阅读-海棠书屋网址在线阅读入口

    海棠书屋小说阅读入口为haitbook.com,备用网址包括htlvbooks.com与longmabookcn.com,另有多条关联站点可供补充访问。 立即进入☞☞☞☞“官方海棠书屋小说阅读☜☜☜☜☜点击进入”; 立即进入☞☞☞☞“海棠书屋网址在线阅读入口☜☜☜☜☜点击进入”; 官方海棠书屋小说阅…

    2026年10月7日 • 用户投稿
    200
  • ie浏览器网页版官方入口-ie高速浏览器绿色版在线入口

    ie浏览器网页版官方入口-ie高速浏览器绿色版在线入口ie浏览器网页版官方入口-ie高速浏览器绿色版在线入口ie浏览器网页版官方入口-ie高速浏览器绿色版在线入口ie浏览器网页版官方入口-ie高速浏览器绿色版在线入口

    IE浏览器网页版官方入口是http://www.iexplore.cc/,提供无需安装的在线IE浏览环境,保留传统界面并支持老旧网页访问、文档预览及ActiveX控件兼容,适用于低配设备和特定系统登录,具备书签导入、历史记录、快捷键等便捷功能,同时采用隔离运行、防钓鱼、禁用自动下载等安全机制保障使用…

    2026年10月7日 • 用户投稿
    000
  • 2025抖音直播带货需要交多少保证金?直播带货怎么开通?

    随着%ignore_a_1%电商的迅猛发展,越来越多的创作者通过直播带货实现了商业变现。然而,在开始使用直播带货功能之前,了解相关规则和费用,特别是保证金的缴纳,是非常必要的。 一、抖音直播带货需要缴纳多少保证金? 抖音直播带货的保证金金额会因不同情况而有所不同,主要受到以下因素的影响: 带货形式与…

    2026年10月7日
    000
  • DMind— 专为Web3领域优化的大模型

    DMind— 专为Web3领域优化的大模型DMind— 专为Web3领域优化的大模型DMind— 专为Web3领域优化的大模型DMind— 专为Web3领域优化的大模型

    DMind是什么 dmind是dmind研究机构发布的专为web3领域优化的大型语言模型。针对区块链、去中心化金融和智能合约等场景深度优化,使用web3数据微调采用rlhf技术对齐。dmind在web3专项基准测试中表现优异,性能远超一线通用模型,推理成本仅为主流大模型的十分之一。包含dmind-1…

    2026年10月7日 • 用户投稿
    100
  • 使用 Hazelcast SQL 查询 IMap 数据:一种轻量级任务管理方案

    使用 Hazelcast SQL 查询 IMap 数据:一种轻量级任务管理方案使用 Hazelcast SQL 查询 IMap 数据:一种轻量级任务管理方案使用 Hazelcast SQL 查询 IMap 数据:一种轻量级任务管理方案使用 Hazelcast SQL 查询 IMap 数据:一种轻量级任务管理方案

    Hazelcast 提供了强大的 SQL 查询能力,可以方便地对 IMap 中的数据进行检索和过滤。本文将介绍如何利用 Hazelcast 的 SQL over Map 功能,将数据库中的任务管理表迁移到 Hazelcast IMap 中,从而减轻数据库压力,提升高并发场景下的性能。 Hazelca…

    2026年10月7日 • 用户投稿
    500
  • 如何为LaravelPassportJWTToken添加自定义Claims,提升授权灵活性?

    如何为LaravelPassportJWTToken添加自定义Claims,提升授权灵活性?如何为LaravelPassportJWTToken添加自定义Claims,提升授权灵活性?如何为LaravelPassportJWTToken添加自定义Claims,提升授权灵活性?如何为LaravelPassportJWTToken添加自定义Claims,提升授权灵活性?

    可以通过一下地址学习composer:学习地址 告别“信息孤岛”:Laravel Passport JWT Token 的痛点 想象一下,你正在开发一个多租户 SaaS 平台,或者一个拥有复杂权限体系的应用。用户通过 Laravel Passport 成功认证后,获得了一个 JWT Token。当这…

    2026年10月7日 • 用户投稿
    500
  • 不藏了!最强麒麟9020高调加持 华为三折叠只卖1万8

    不藏了!最强麒麟9020高调加持 华为三折叠只卖1万8不藏了!最强麒麟9020高调加持 华为三折叠只卖1万8不藏了!最强麒麟9020高调加持 华为三折叠只卖1万8不藏了!最强麒麟9020高调加持 华为三折叠只卖1万8

    加量不加价,余承东刚刚发布了华为第二款三折叠手机——mate xts非凡大师。 最受瞩目的是全新麒麟9020芯片正式上机,搭配HarmonyOS 5.1智能操作系统,整机性能提升36%。 这也是华为麒麟芯片,时隔四年多再次公开更新。 不藏了,这次华为芯片真的不藏了。 利用鸿蒙生态,Mate XTs首…

    2026年10月7日 • 用户投稿
    200
  • Java如何实现智能运维?异常检测算法

    Java如何实现智能运维?异常检测算法Java如何实现智能运维?异常检测算法Java如何实现智能运维?异常检测算法Java如何实现智能运维?异常检测算法

    异常检测算法在java智能运维中至关重要,常用方法包括统计方法、机器学习和时间序列分析。1. 统计方法如均值与标准差、z-score用于识别偏离均值的数据点;2. 机器学习方法如isolation forest、one-class svm和k-means适用于复杂数据集的异常识别;3. 时间序列分析…

    2026年10月7日 • 用户投稿
    100
  • 如何解决Symfony应用中对象间繁琐的属性映射问题,retailcrm/auto-mapper-bundle助你轻松实现数据转换

    如何解决Symfony应用中对象间繁琐的属性映射问题,retailcrm/auto-mapper-bundle助你轻松实现数据转换如何解决Symfony应用中对象间繁琐的属性映射问题,retailcrm/auto-mapper-bundle助你轻松实现数据转换如何解决Symfony应用中对象间繁琐的属性映射问题,retailcrm/auto-mapper-bundle助你轻松实现数据转换如何解决Symfony应用中对象间繁琐的属性映射问题,retailcrm/auto-mapper-bundle助你轻松实现数据转换

    可以通过一下地址学习composer:学习地址 在现代的 PHP 应用,特别是基于 Symfony 框架的项目中,我们经常会遇到这样的场景:你需要从数据库中取出数据(Entity 对象),将其转换为一个用于 API 响应或表单展示的数据传输对象(DTO),或者反过来,将用户提交的表单数据映射回一个实…

    2026年10月7日 • 用户投稿
    300
  • 蚂蚁集团入股多家芯片企业,加速布局 AI 算力基础设施

    蚂蚁集团入股多家芯片企业,加速布局 AI 算力基础设施蚂蚁集团入股多家芯片企业,加速布局 AI 算力基础设施蚂蚁集团入股多家芯片企业,加速布局 AI 算力基础设施蚂蚁集团入股多家芯片企业,加速布局 AI 算力基础设施

    近日,蚂蚁集团通过其下属投资平台上海云玡企业管理咨询有限公司,在短短七天内相继完成对昕原半导体、烨知芯科技以及云合智网三家芯片企业的投资或股权增持,进一步强化在AI算力底层基础设施领域的布局。 算家云 高效、便捷的人工智能算力服务平台 37 查看详情 这一系列动作延续了蚂蚁在芯片赛道的长期投入。自2…

    2026年10月7日 • 用户投稿
    000
  • VSCode如何设置智能代码导航 VSCode符号跳转与引用查找的高效技巧

    确保安装对应语言的官方扩展,如python或typescript相关插件,以提供基础代码导航功能;2. 配置settings.json文件,针对语言设置如”typescript.preferences.importmodulespecifier”等选项优化导航行为;3. 安装…

    2026年10月7日
    100
  • 海尔智家与用户共创数字营销新范式

    海尔智家与用户共创数字营销新范式海尔智家与用户共创数字营销新范式海尔智家与用户共创数字营销新范式海尔智家与用户共创数字营销新范式

    8月28日,海尔智家发布2025年半年报。数据显示,公司上半年实现营业收入1564.94亿元,同比增长10.2%;归母净利润达120.33亿元,同比增长15.6%,营收与利润双双创下历史新高。在次日举行的中报交流会上,针对投资者关注的国内数字化营销转型进展,海尔智家作出回应,表示公司正围绕全流程用户…

    2026年10月7日 • 用户投稿
    000
  • 如何创建自己的Composer包并发布到Packagist?

    如何创建自己的Composer包并发布到Packagist?如何创建自己的Composer包并发布到Packagist?如何创建自己的Composer包并发布到Packagist?如何创建自己的Composer包并发布到Packagist?

    答案是创建并发布Composer包到Packagist只需五步:准备项目结构、编写composer.json、推送到公共Git仓库、提交到Packagist、设置自动更新。首先确保项目包含src/、composer.json和README.md;接着配置composer.json,明确包名、命名空间…

    2026年10月7日 • 用户投稿
    1300
  • 《夺宝奇兵:古老之圈》更新上线 现已支持RTX毛发

    《夺宝奇兵:古老之圈》更新上线 现已支持RTX毛发《夺宝奇兵:古老之圈》更新上线 现已支持RTX毛发《夺宝奇兵:古老之圈》更新上线 现已支持RTX毛发《夺宝奇兵:古老之圈》更新上线 现已支持RTX毛发

    英伟达宣布四款新作——《夺宝奇兵:古老之圈》“巨人教团”dlc、《微软模拟飞行2024》、《时间旅者:重生曙光》、《地狱即我们》现已支持dlss 4多帧生成! 此外,《夺宝奇兵:古老之圈:巨人教团》同步推出游戏更新,为DLC及游戏本体中的关键角色添加英伟达RTX Hair技术,带来更逼真的头发渲染效…

    2026年10月7日 • 用户投稿
    100
  • 百度搜索记录同步怎么关闭_百度关闭搜索记录同步功能

    百度搜索记录同步怎么关闭_百度关闭搜索记录同步功能百度搜索记录同步怎么关闭_百度关闭搜索记录同步功能百度搜索记录同步怎么关闭_百度关闭搜索记录同步功能百度搜索记录同步怎么关闭_百度关闭搜索记录同步功能

    1、在百度App“我的”页面进入设置,选择“账号与安全”,关闭“搜索记录同步”功能;2、清除搜索历史并关闭“保存搜索记录”选项,防止本地记录生成;3、登录百度账号中心,于隐私设置中关闭跨设备同步,全面停止搜索记录在各设备间的同步与保存。 如果您希望停止百度搜索记录在不同设备间的自动同步,以保护个人隐…

    2026年10月7日 • 用户投稿
    000

发表回复

登录后才能评论
关注微信