七夕特别篇 | 浪漫的Bug

这篇具有很好参考价值的文章主要介绍了七夕特别篇 | 浪漫的Bug。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

Hello!各位C站的朋友们大家好啊!在长达 七个月 的停更后,小刘又回来了!

在这里,小刘要郑重地向大家道个歉,因为学业繁重,所以小刘没能挤出时间来写博客,让朋友们久等了!

七夕特别篇 | 浪漫的Bug,bug,c++,数学,原力计划

如今,正值七夕佳节(好像过了,但不重要),小刘写了点儿有意思的东西请大家阅览,如果您看完后觉得还不错,那还请您别忘了留下一点儿建议或是点评哦!

一、迷失的爱情漩涡(多线程中的错误同步)

1.1 Bug 背景

假设有两个线程 ABAB 竞争访问一个共享变量 loveValue,代表两位恋人之间的爱情值。我们的目标是保证线程 AB 能够正常地交替更新这个爱情值,以模拟恋人们甜蜜的互动。

初始代码中涉及两个关键函数:increaseLovedecreaseLove,分别用于增加和减少 loveValue 值。

理想的程序工作流程示意图

代码如下:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex loveMutex;
std::condition_variable loveCV;
int loveValue = 50;
bool isIncreasing = true;

void increaseLove(int amount) {
    std::lock_guard<std::mutex> lock(loveMutex);
    loveValue += amount;
    isIncreasing = true;
    loveCV.notify_one();
}

void decreaseLove(int amount) {
    std::unique_lock<std::mutex> lock(loveMutex);
    loveCV.wait(lock, [] { return !isIncreasing; });
    loveValue -= amount;
    isIncreasing = false;
    lock.unlock();  // 释放锁,以便其他线程可以获取权限
    loveCV.notify_one();
}

int main() {
    std::thread loverA([&]() {
        for (int i = 0; i < 10; ++i) {
            increaseLove(10);
        }
    });

    std::thread loverB([&]() {
        for (int i = 0; i < 10; ++i) {
            decreaseLove(5);
        }
    });

    loverA.join();
    loverB.join();

    std::cout << "Final Love Value: " << loveValue << std::endl;

    return 0;
}

1.2 Bug 分析

尽管代码看起来似乎没有问题,但实际上却隐藏着一个隐蔽的陷阱。当线程 A 执行 increaseLove 函数时,它会锁定 loveMutex,然后更新 loveValue。但是,线程 B 试图执行 decreaseLove 函数时,由于 loveMutex 被线程 A 锁定,它将被阻塞,无法执行。反之亦然。

这就意味着线程 AB 之间的爱情互动被锁定,无法交替进行,就像陷入了一个不可逾越的障碍,无法真正地感受到彼此的情感。

Bug 示意图

1.3 Bug 解决

解决这个问题就得用到一个更为精细的同步机制,以允许线程 AB 在不互相阻塞的情况下更新 loveValue。我们可以使用条件变量,使得线程 AB 可以在适当的时机等待和唤醒。

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex loveMutex;
std::condition_variable loveCV;
int loveValue = 50;
bool isIncreasing = true;

void increaseLove(int amount) {
    std::lock_guard<std::mutex> lock(loveMutex);
    loveValue += amount;
    isIncreasing = true;
    loveCV.notify_one();
}

void decreaseLove(int amount) {
    std::unique_lock<std::mutex> lock(loveMutex);
    loveCV.wait(lock, [] { return !isIncreasing; });
    loveValue -= amount;
    isIncreasing = false;
    loveCV.notify_one();
}

int main() {
    std::thread loverA([&]() {
        for (int i = 0; i < 10; ++i) {
            increaseLove(10);
        }
    });

    std::thread loverB([&]() {
        for (int i = 0; i < 10; ++i) {
            decreaseLove(5);
        }
    });

    loverA.join();
    loverB.join();

    std::cout << "Final Love Value: " << loveValue << std::endl;

    return 0;
}

爱情有着奇妙的魔力,它使一个人为另一个人所倾倒 ——瑟伯与怀特

二、心形积分之恋(心形面积计算中的数值积分误差)

1.1 Bug 背景

1.1.1 背景

我的目的是计算心形函数面积,心形函数的参数方程可以表示为:
x = 16 ⋅ sin ⁡ 3 ( t ) , y = 13 ⋅ cos ⁡ ( t ) − 5 ⋅ cos ⁡ ( 2 t ) − 2 ⋅ cos ⁡ ( 3 t ) − cos ⁡ ( 4 t ) x = 16 \cdot \sin^3(t), \quad y = 13 \cdot \cos(t) - 5 \cdot \cos(2t) - 2 \cdot \cos(3t) - \cos(4t) x=16sin3(t),y=13cos(t)5cos(2t)2cos(3t)cos(4t)

七夕特别篇 | 浪漫的Bug,bug,c++,数学,原力计划

(Python绘制的函数,代码附到结尾了)

1.1.2 数学模型

我们需要计算参数方程描述的曲线的面积。这可以通过计算积分来实现,其中 t t t 的范围通常从 0 0 0 2 π 2π 2π

心形曲线的面积可以表示为如下积分:

A = 1 2 ∫ 0 2 π y ( t ) ⋅ x ′ ( t )   d t A = \frac{1}{2} \int_{0}^{2\pi} y(t) \cdot x'(t) \, dt A=2102πy(t)x(t)dt

1.2 Bug 分析

1.2.1 初始代码

代码如下:

#include <iostream>
#include <cmath>

const double pi = 3.14159265358979323846;

// 心形的参数方程
double x(double t) {
    return 16 * pow(sin(t), 3);
}

double y(double t) {
    return 13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t);
}

// 使用数值积分计算面积的函数
double calculateArea(double a, double b, int n) {
    double h = (b - a) / n;
    double area = 0.0;

    for (int i = 0; i < n; ++i) {
        double x_left = x(a + i * h);
        double x_right = x(a + (i + 1) * h);
        double y_mid = (y(a + i * h) + y(a + (i + 1) * h)) / 2.0;
        area += y_mid * (x_right - x_left);
    }

    return area;
}

int main() {
    double a = 0.0;
    double b = 2 * pi;
    int n = 10000;

    double area = calculateArea(a, b, n);

    std::cout << "Heart Area: " << area << std::endl;

    return 0;
}

1.2.2 代码工作流程图

理想的代码工作流程图

1.2.3 代码分析

当我们考虑使用矩形法进行数值积分时,我们希望通过将积分区间划分为多个小矩形,对每个小矩形的面积进行累加来逼近曲线所围成的区域面积。在这个 Bug 中,我们的目标是计算心形曲线所包围的区域面积,然而,由于在计算面积时忽略了 x ′ ( t ) x′(t) x(t),导致了错误的结果。

在原始代码中,我们使用了一个简单的循环来遍历积分区间的小段,每个小段的左右边界分别对应函数 x ( t ) x(t) x(t) 的值。我们计算了每个小段中心点的 y 值(即 ( y ( a + i ⋅ h ) + y ( a + ( i + 1 ) ⋅ h ) ) / 2.0 (y(a+i⋅h)+y(a+(i+1)⋅h))/2.0 (y(a+ih)+y(a+(i+1)h))/2.0 ),然后将其乘以区间长度 h h h,最终累加得到近似的区域面积。但在这个过程中,我们遗漏了一个重要的细节:每个小段的宽度(即 h h h)应该乘以 x ′ ( t ) x′(t) x(t) 才能得到正确的面积。

在数学上,当我们计算曲线上一点的切线斜率,即导数,我们可以通过求解 x ( t ) x(t) x(t) 的导数来得到 x ′ ( t ) x′(t) x(t)。因此,在计算每个小段的面积时,我们应该使用 x ′ ( t ) x′(t) x(t) 乘以 h h h 而不仅仅是 h h h,以更精确地逼近曲线围成的区域。

1.3 Bug解决

当运行初始的错误代码时,我们会得到一个错误的心形区域面积。这是因为在计算面积时,我们忽略了 x ′ ( t ) x′(t) x(t) 这个重要因素,导致积分的结果与真实面积相差较大。

假设我们使用以下的参数来运行初始错误代码:

double a = 0.0;
double b = 2 * pi;
int n = 10000;

运行后,输出的心形区域面积可能会是:

Heart Area: 31.4159

实际上,正确的心形区域面积应该接近 82.743 82.743 82.743,这恰恰是因为积分计算没有考虑到参数方程的导数 x ′ ( t ) x′(t) x(t)。为了修复这个问题,我们需要在计算面积时乘以 x ′ ( t ) x′(t) x(t)

// 使用数值积分计算面积的函数
double calculateArea(double a, double b, int n) {
    double h = (b - a) / n;
    double area = 0.0;

    for (int i = 0; i < n; ++i) {
        double t = a + i * h;
        double x_left = x(t);
        double x_right = x(t + h);
        double y_mid = (y(t) + y(t + h)) / 2.0;
        area += y_mid * (x_right - x_left);
    }

    return area;
}

在修正后的代码中,我们将 x ( t ) x(t) x(t) x ( t + h ) x(t+h) x(t+h) 分别作为小区间的左边界和右边界,并使用中点的 y y y 值乘以小区间的宽度来计算近似的面积。这个修正考虑了 x ′ ( t ) x′(t) x(t) 的影响,使得程序能够更准确地计算心形曲线所围成的区域面积。

三、总结

Bug 1: 多线程环境中的同步问题

这个Bug发生在一个涉及多线程的环境中。通过竞争访问一个共享变量,在代码中模拟了两位恋人之间的爱情值互动。尽管看起来没有问题,但实际上由于同步机制的缺失,线程 A 和 B 之间的爱情互动被锁定,无法正常交替进行,导致无法真实感受到彼此的情感。通过重新设计同步机制,我们解决了这个问题,使得线程 A 和 B 能够在不互相阻塞的情况下更新爱情值,实现了恋人之间情感的自由流动。

Bug 2: 心形函数面积计算错误

这个Bug涉及到计算心形函数所围成的区域面积。初始代码使用矩形法计算数值积分来近似区域面积,但在计算过程中忽略了心形曲线的导数。因此,计算得到的区域面积并不准确。通过引入导数修正,我们重新计算每个小段的面积,考虑了函数的变化率,从而得到了更精确的区域面积。这个修复展示了数学模型与代码之间的相互作用,揭示了在复杂问题中精确建模的重要性。文章来源地址https://www.toymoban.com/news/detail-695439.html

附录:心形函数代码

import numpy as np
import matplotlib.pyplot as plt

# 心形的参数方程
def x(t):
    return 16 * np.sin(t)**3

def y(t):
    return 13 * np.cos(t) - 5 * np.cos(2*t) - 2 * np.cos(3*t) - np.cos(4*t)

# 生成从0到2*pi对应的t值
t_values = np.linspace(0, 2*np.pi, 1000)

# 计算相应的x和y值
x_values = x(t_values)
y_values = y(t_values)

# 绘制心形
plt.figure(figsize=(6, 6))
plt.plot(x_values, y_values, color='red')
plt.title('Heart Shape Function')
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.axis('equal')  # x轴和y轴的相等纵横比
plt.show()

到了这里,关于七夕特别篇 | 浪漫的Bug的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 七夕特别篇|用Python绘画牛郎织女在鹊桥相见

    大家好,我是辰哥~ 明天就是七夕节,首先提前祝福有伴侣的小伙伴,七夕快乐,没有伴侣的小伙伴,明天就会找到伴侣,(给看到这句话的你好运加持,哈哈哈)。 作为会Python的我们必须做点好玩且有意义的东西。在本文中辰哥使用turtle库进行绘制,如果不清楚turtle的大概

    2023年04月08日
    浏览(46)
  • 【AI绘画--七夕篇】:七夕特别教程,使用SDXL绘制你的心上人(Stable Diffusion)(封神榜—妲己)

    七夕特别教程,快来使用SDXL画出一个女朋友吧! Stable Diffusion是一种基于潜在扩散模型(Latent Diffusion Models,简称LDM)的模型,它最近在各个平台上都引起了广泛的关注,因为其在文本到图像(text2img)或图像到图像(img2img)的应用中都展示出了非常惊艳的效果。 Stable Diffu

    2024年02月11日
    浏览(48)
  • 如何判断bug是前端bug还是后端bug

    1.前后端bug 特征 :     前端主要负责显示数据,后端主要负责处理数据、存储数据,前后端主要通过接口进行数据交换。      前端bug的特征:     界面显示类问题:如文字大小不一,控件颜色不搭,控件不整齐,静态界面错误;     页面布局类问题:文字排版没有统一,

    2024年02月09日
    浏览(41)
  • BUG分析以及BUG定位

     一般来说bug大多数存在于3个模块: 1、前台界面,包括界面的显示,兼容性,数据提交的判断,页面的跳转等等,这些bug基本都是一眼可见的,不太需要定位,当然也不排除一些特殊情况,本身数据传过来的时候就有问题,所以显示会出问题的情况(这个后面会说到)。

    2024年02月15日
    浏览(34)
  • 【bug】bug集结地

    bug1:无法连接虚拟设备 ide1:0,因为主机上没有相应的设备。您要在每次开启此虚拟机时都尝试连接此虚拟设备吗? 原因:ide1:0 是虚拟机的光驱,配置选项是连接物理驱动器,错误原因是虚拟主机没有镜像系统所致,删除虚拟机的光驱,或者改成光盘镜像就可以了, 解决:具体

    2024年02月11日
    浏览(37)
  • 在数据库造数据发现的bug也是bug

           上个月,我和开发小哥讨论过一个问题,开发小哥专门提醒我,页面上新增功能尽可能在前端造一些数据去测试,如果直接从数据库里插入的数据,定位问题还是有些说不清楚。 讨论的过程和细节就是以下的对话内容: 测试小姐姐: 企业设备翻页查询的时候报这个错

    2024年02月02日
    浏览(48)
  • NEFU离散数学实验特别篇1-树和图

    离散数学中,树是一种重要的数据结构,它是一种无向连通图,并且不存在环。下面是树的相关概念和公式: 1. 顶点数为n的树,边数为n-1。 2. 度数为k的树中有k个分支。 3. 一棵树中最多只有两个度数大于1的顶点,这些顶点称为树的端点或叶子,其余顶点称为分支或内部点。

    2024年02月06日
    浏览(38)
  • 一篇普通的bug日志——bug的尽头是next吗?

    问题代码: 原因: parameters 后面少了个括号。 这段报错可以用如下代码重现出来: 原因: 传给 {:4f} 的应该是一个浮点数 数值 ,而 x 是 numpy 的数组,于是类型不匹配。我们只需将 x 转为浮点型即可,正确代码如下: 描述 学习预训练模型的 fine-tune 时,将 AI Studio 上能跑的

    2024年02月02日
    浏览(26)
  • 项目出bug,找不到bug,如何拉回之前的版本

    本文为转载于「闪耀太阳a」的原创文章原文链接:https://blog.csdn.net/Gufang617/article/details/119929145 怎么从gitee上拉取代码 1.首先找到gitee上想要拉取得代码URL地址 点击复制这里的https地址 1 ps:(另外一种方法,很快,一行代码即可拉取)找到本地一个文件夹,鼠标右键git bash,在

    2024年02月14日
    浏览(28)
  • 解决相机库CameraView多滤镜拍照错乱的BUG (一) : 复现BUG

    这段时间,在使用 natario1/CameraView 来实现带滤镜的 预览 、 拍照 、 录像 功能。 由于 CameraView 封装的比较到位,在项目前期,的确为我们节省了不少时间。 但随着项目持续深入,对于 CameraView 的使用进入深水区,逐渐出现满足不了我们需求的情况。 Github 中的 issues 中,有些

    2024年02月03日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包