No22. 获取指定范围内的随机数

本文详细介绍了Java中Math.random()方法的使用,包括如何生成1-100之间的随机数和[m,n]区间内的随机数。同时,展示了如何将double值保留三位小数,并给出了相关代码示例,如获取[1.2, 3.3]和[1, 5]区间内的随机数。此外,还提及了Math类的其他方法,如ceil、round、floor和pow的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

  • Math.random用法
  • 获取1-100之间的随机数
  • 获取m~n之间的随机数
  • double保留三位小数


一:Math.random用法
public static double random()
返回一个 double值与一个积极的迹象,大于或等于 0.0小于 1.0。返回值与选择伪随机(大约),范围分布均匀。 
二: 获取1-100之间的随机数
public static int getRandom(){
    return (int)(Math.random()*100)+1;
}
三:获取[m,n]之间的随机数
  • 小数

    Math.random()*(右-左)+左

  • 整数

    Math.random()*(右-左+1)+左

import java.util.Arrays;

public class TestRandom {
    public static void main(String[] args) {
        int[] a = new int[6];

        for(int i=0;i<1000000;i++){
//            // [1.2,3.3] 随机数
//            // double x = Math.random()*(3.3-1.2)+1.2;
//            double x = Math.random()*(1.2-0.5)+0.5;
//            System.out.println(x);
//            if(x>1.2||x<0.5){
//                System.out.println(x);
//            }

            // [1,5]的随机值
            double x = Math.random()*(5-1+1)+1;
            System.out.println((int)x);
            a[(int)x]++;
        }
        
        System.out.println(Arrays.toString(a));
    }
}
四: double保留三位小数
double d = Double.valueOf(String.format("%.3f",Math.random()));

五:的其他方法

1> 换底公式

在这里插入图片描述


2> ceil、round、floor、pow
public class Main{
	public static void main(String[] args) {
        double a = 2.5;
        System.out.println(Math.ceil(a));   // 3.0
        System.out.println(Math.round(a));  // 3
        System.out.println(Math.floor(a));  // 2.0

        System.out.println(Math.log(4));              // 1.3862943611198906
        System.out.println(Math.log(4)/Math.log(2));  // 2.0

        System.out.println(Math.pow(2.5,2.5));        // 9.882117688026186
	}
}
<think>好的,我现在需要帮助用户解决在STM32F103单片机上电时生成不同范围的随机数的问题。首先,我得回忆一下STM32F103的硬件特性。STM32F103系列没有内置的真随机数生成器(TRNG),所以只能使用伪随机数算法,比如线性同余生成器(LCG)。但伪随机数需要种子,如果每次上电种子相同,生成的序列就会重复,所以关键在于如何获取不同的种子。 用户提到“上电时生成不同范围的随机数”,所以可能需要根据不同的范围调整生成的数值。比如,用户可能需要0-100或者50-150之间的随机数,这时候可以通过取模和加法来调整基础随机数。 接下来,我需要考虑如何获取不同的种子。常见的方法是利用未初始化的RAM值,因为每次上电时RAM的内容是随机的。或者使用ADC读取悬空的引脚电压,作为噪声源。此外,RTC的备份寄存器也是一个选项,但需要电池供电才能保持,可能用户不一定有这种配置。 然后,我得验证这些方法的可行性。比如,使用ADC读取悬空引脚,可能会有环境噪声,但需要配置ADC正确,并多次采样取平均或处理。而使用RAM中的未初始化变量,可能需要确保该区域在启动时未被初始化,这取决于启动文件和编译器设置。例如,使用__attribute__((section(".noinit")))来保留变量不被初始化。 接下来,代码示例方面,需要展示如何初始化种子,比如使用HAL库的ADC读取,或者获取RAM值,然后使用srand()设置种子,之后用rand()生成随机数,再映射到特定范围。 还需要考虑用户可能的误区,比如直接使用time(NULL)作为种子,但在单片机中没有实时时钟的话,time()可能返回固定值。所以必须使用硬件相关的随机源。 另外,关于随机数范围,用户可能需要不同的范围,所以示例中应该展示如何将生成的随机数调整到指定范围,比如使用模运算和偏移。 最后,需要检查代码的正确性,比如ADC的初始化是否正确,是否启用了时钟,GPIO模式是否正确设置为模拟输入。同时提醒用户悬空引脚可能受到干扰,最好使用未连接的引脚。 总结步骤:1. 获取随机种子(ADC或RAM);2. 初始化srand;3. 生成rand();4. 调整到所需范围。同时提供两种方法的示例代码,并说明注意事项。</think>为了在STM32F103上电时生成不同范围的随机数,可通过硬件特性(如ADC噪声或未初始化RAM)生成种子,再结合伪随机算法实现。以下是具体实现方法: ### 一、硬件随机种子生成原理 1. **利用ADC噪声**:读取悬空ADC通道的末位噪声作为熵源[^1] 2. **未初始化RAM值**:STM32上电时未初始化RAM区域的值具有随机性 $$ \text{随机种子} = \sum_{i=0}^{n}(ADC\_Read() \gg 4) \oplus RAM\_Value[i] $$ ### 二、代码实现(基于HAL库) ```c // 在noinit段定义未初始化变量 __attribute__((section(".noinit"))) uint32_t ram_seed; void RNG_Init(void) { // 方法1:使用ADC噪声 ADC_HandleTypeDef hadc; hadc.Instance = ADC1; HAL_ADC_Start(&hadc); uint32_t adc_seed = HAL_ADC_GetValue(&hadc) & 0xFF; // 方法2:结合RAM值 uint32_t seed = adc_seed ^ ram_seed; srand(seed); } int Get_Random(int min, int max) { return min + (rand() % (max - min + 1)); } ``` ### 三、配置注意事项 1. ADC配置: ```c void ADC_Config(void) { __HAL_RCC_ADC1_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_0; // 使用悬空的ADC通道(如PA0) GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` 2. 上电初始化流程: ```c int main(void) { HAL_Init(); SystemClock_Config(); ADC_Config(); RNG_Init(); int temp = Get_Random(-20, 50); // 生成-20~50范围的随机数 while(1) { /*...*/ } } ``` ### 四、性能优化建议 1. 多次采样取异或:建议连续读取4次ADC值进行异或运算 2. 混合时钟抖动:结合系统时钟计数器LSB位 ```c seed ^= (DWT->CYCCNT & 0xFF); // 需要先启用DWT计数器 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值