You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LeetCode圆内随机点生成问题排查:结果精度异常原因?

圆内随机点生成精度异常排查

问题描述

在完成LeetCode圆内随机点生成题目时,编写了如下C++代码:

class Solution {
private:
double c_radius;
double xcenter;
double ycenter;

public:
    Solution(double radius, double x_center, double y_center) {
    c_radius = radius;
    xcenter = x_center;
    ycenter = y_center;  
}

vector<double> randPoint() {
    double randomradius= (sqrt((double)rand()) / RAND_MAX) * c_radius;
    double randomangle= ((double)rand() / RAND_MAX) * 360.0;
    double yp= sin(randomangle)*randomradius;
    double xp= cos(randomangle)*randomradius;
    std::vector<double> point= {xp+xcenter, yp+ycenter};
    return point; 
}
};

当测试输入为[[0.01,-73839.1,-3289891.3]]时,生成的点始终是类似[-73839.10000,-3289891.30000]的固定精度值,无法得到预期的带更多小数位的随机点(如[-73839.10006,-3289891.30228]),请求排查问题是否出在数学逻辑上。

问题分析与解决

1. 核心问题:三角函数的角度单位错误

C++标准库中的sin()和cos()函数要求输入参数为弧度值,但当前代码中生成的randomangle是0~360的角度值,直接传入会导致计算严重偏差:

  • 当角度值很小时(比如0.1度),对应的弧度值约为0.001745,而直接传入0.1作为弧度的话,sin(0.1)≈0.0998,cos(0.1)≈0.995,两者差距极大。
  • 对于测试用例中的极小半径(0.01),错误的角度计算会导致偏移量xp、yp极小,加上中心坐标的大数后,小数部分被精度截断,最终显示为固定值。

2. 修正方案

将角度转换为弧度值,直接生成0~2π范围内的随机弧度即可:

#include <cmath> // 需包含此头文件以使用sin、cos和M_PI

class Solution {
private:
    double c_radius;
    double xcenter;
    double ycenter;

public:
    Solution(double radius, double x_center, double y_center) {
        c_radius = radius;
        xcenter = x_center;
        ycenter = y_center;  
    }

    vector<double> randPoint() {
        // 保持半径的均匀分布逻辑(sqrt是正确的,避免点集中在圆心)
        double r = sqrt(static_cast<double>(rand()) / RAND_MAX) * c_radius;
        // 生成0到2π的随机弧度
        double theta = static_cast<double>(rand()) / RAND_MAX * 2 * M_PI;
        double xp = cos(theta) * r;
        double yp = sin(theta) * r;
        return {xp + xcenter, yp + ycenter};
    }
};

3. 额外优化建议

  • 如果编译器不支持M_PI,可以手动定义:#define M_PI 3.14159265358979323846
  • rand()的精度有限(通常是15位范围),对于极小半径场景,可改用C++11的<random>库提升随机数精度,示例:
#include <random>

class Solution {
private:
    double c_radius;
    double xcenter;
    double ycenter;
    std::mt19937 gen;
    std::uniform_real_distribution<double> dist;

public:
    Solution(double radius, double x_center, double y_center) 
        : c_radius(radius), xcenter(x_center), ycenter(y_center), 
          gen(std::random_device{}()), dist(0.0, 1.0) {}

    vector<double> randPoint() {
        double r = sqrt(dist(gen)) * c_radius;
        double theta = dist(gen) * 2 * M_PI;
        double xp = cos(theta) * r;
        double yp = sin(theta) * r;
        return {xp + xcenter, yp + ycenter};
    }
};

内容的提问来源于stack exchange,提问作者MP3D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:15:00