免费推广店铺的网站,小米装修,做一个平台 网站服务器搭建,江西seo文章目录 前言一、迷失的爱情漩涡#xff08;多线程中的错误同步#xff09;1.1 Bug 背景1.2 Bug 分析1.3 Bug 解决 二、心形积分之恋#xff08;心形面积计算中的数值积分误差#xff09;1.1 Bug 背景1.1.1 背景1.1.2 数学模型 1.2 Bug 分析1.2.1 初始代码1.2.2 代码工作流… 文章目录 前言一、迷失的爱情漩涡多线程中的错误同步1.1 Bug 背景1.2 Bug 分析1.3 Bug 解决 二、心形积分之恋心形面积计算中的数值积分误差1.1 Bug 背景1.1.1 背景1.1.2 数学模型 1.2 Bug 分析1.2.1 初始代码1.2.2 代码工作流程图1.2.3 代码分析 1.3 Bug解决 三、总结Bug 1: 多线程环境中的同步问题Bug 2: 心形函数面积计算错误 附录心形函数代码 前言
Hello各位C站的朋友们大家好啊在长达 七个月 的停更后小刘又回来了
在这里小刘要郑重地向大家道个歉因为学业繁重所以小刘没能挤出时间来写博客让朋友们久等了 如今正值七夕佳节好像过了但不重要小刘写了点儿有意思的东西请大家阅览如果您看完后觉得还不错那还请您别忘了留下一点儿建议或是点评哦
一、迷失的爱情漩涡多线程中的错误同步
1.1 Bug 背景
假设有两个线程 A 和 BA 和 B 竞争访问一个共享变量 loveValue代表两位恋人之间的爱情值。我们的目标是保证线程 A 和 B 能够正常地交替更新这个爱情值以模拟恋人们甜蜜的互动。
初始代码中涉及两个关键函数increaseLove 和 decreaseLove分别用于增加和减少 loveValue 值。 #mermaid-svg-0FubI1crc5tXQ3p8 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-0FubI1crc5tXQ3p8 .error-icon{fill:#552222;}#mermaid-svg-0FubI1crc5tXQ3p8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0FubI1crc5tXQ3p8 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-0FubI1crc5tXQ3p8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0FubI1crc5tXQ3p8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0FubI1crc5tXQ3p8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0FubI1crc5tXQ3p8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0FubI1crc5tXQ3p8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0FubI1crc5tXQ3p8 .marker.cross{stroke:#333333;}#mermaid-svg-0FubI1crc5tXQ3p8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0FubI1crc5tXQ3p8 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-0FubI1crc5tXQ3p8 text.actortspan{fill:black;stroke:none;}#mermaid-svg-0FubI1crc5tXQ3p8 .actor-line{stroke:grey;}#mermaid-svg-0FubI1crc5tXQ3p8 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-0FubI1crc5tXQ3p8 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-0FubI1crc5tXQ3p8 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-0FubI1crc5tXQ3p8 .sequenceNumber{fill:white;}#mermaid-svg-0FubI1crc5tXQ3p8 #sequencenumber{fill:#333;}#mermaid-svg-0FubI1crc5tXQ3p8 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-0FubI1crc5tXQ3p8 .messageText{fill:#333;stroke:#333;}#mermaid-svg-0FubI1crc5tXQ3p8 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-0FubI1crc5tXQ3p8 .labelText,#mermaid-svg-0FubI1crc5tXQ3p8 .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-0FubI1crc5tXQ3p8 .loopText,#mermaid-svg-0FubI1crc5tXQ3p8 .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-0FubI1crc5tXQ3p8 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-0FubI1crc5tXQ3p8 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-0FubI1crc5tXQ3p8 .noteText,#mermaid-svg-0FubI1crc5tXQ3p8 .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-0FubI1crc5tXQ3p8 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-0FubI1crc5tXQ3p8 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-0FubI1crc5tXQ3p8 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-0FubI1crc5tXQ3p8 .actorPopupMenu{position:absolute;}#mermaid-svg-0FubI1crc5tXQ3p8 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-0FubI1crc5tXQ3p8 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-0FubI1crc5tXQ3p8 .actor-man circle,#mermaid-svg-0FubI1crc5tXQ3p8 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-0FubI1crc5tXQ3p8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} A loveValue increaseLove / decreaseLove A loveValue #mermaid-svg-fZ6a8InH2PqggaNz {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-fZ6a8InH2PqggaNz .error-icon{fill:#552222;}#mermaid-svg-fZ6a8InH2PqggaNz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fZ6a8InH2PqggaNz .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-fZ6a8InH2PqggaNz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fZ6a8InH2PqggaNz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fZ6a8InH2PqggaNz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fZ6a8InH2PqggaNz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fZ6a8InH2PqggaNz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fZ6a8InH2PqggaNz .marker.cross{stroke:#333333;}#mermaid-svg-fZ6a8InH2PqggaNz svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fZ6a8InH2PqggaNz .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fZ6a8InH2PqggaNz text.actortspan{fill:black;stroke:none;}#mermaid-svg-fZ6a8InH2PqggaNz .actor-line{stroke:grey;}#mermaid-svg-fZ6a8InH2PqggaNz .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-fZ6a8InH2PqggaNz .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-fZ6a8InH2PqggaNz #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-fZ6a8InH2PqggaNz .sequenceNumber{fill:white;}#mermaid-svg-fZ6a8InH2PqggaNz #sequencenumber{fill:#333;}#mermaid-svg-fZ6a8InH2PqggaNz #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-fZ6a8InH2PqggaNz .messageText{fill:#333;stroke:#333;}#mermaid-svg-fZ6a8InH2PqggaNz .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fZ6a8InH2PqggaNz .labelText,#mermaid-svg-fZ6a8InH2PqggaNz .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-fZ6a8InH2PqggaNz .loopText,#mermaid-svg-fZ6a8InH2PqggaNz .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-fZ6a8InH2PqggaNz .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-fZ6a8InH2PqggaNz .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-fZ6a8InH2PqggaNz .noteText,#mermaid-svg-fZ6a8InH2PqggaNz .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-fZ6a8InH2PqggaNz .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fZ6a8InH2PqggaNz .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fZ6a8InH2PqggaNz .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-fZ6a8InH2PqggaNz .actorPopupMenu{position:absolute;}#mermaid-svg-fZ6a8InH2PqggaNz .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-fZ6a8InH2PqggaNz .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-fZ6a8InH2PqggaNz .actor-man circle,#mermaid-svg-fZ6a8InH2PqggaNz line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-fZ6a8InH2PqggaNz :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} B loveValue increaseLove / decreaseLove B loveValue 理想的程序工作流程示意图 代码如下
#include iostream
#include thread
#include mutexstd::mutex loveMutex;
int loveValue 50;void increaseLove(int amount) {std::lock_guardstd::mutex lock(loveMutex);loveValue amount;
}void decreaseLove(int amount) {std::lock_guardstd::mutex lock(loveMutex);loveValue - amount;
}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 锁定它将被阻塞无法执行。反之亦然。
这就意味着线程 A 和 B 之间的爱情互动被锁定无法交替进行就像陷入了一个不可逾越的障碍无法真正地感受到彼此的情感。 #mermaid-svg-WIOujDuAWe9rHL4V {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-WIOujDuAWe9rHL4V .error-icon{fill:#552222;}#mermaid-svg-WIOujDuAWe9rHL4V .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WIOujDuAWe9rHL4V .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-WIOujDuAWe9rHL4V .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WIOujDuAWe9rHL4V .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WIOujDuAWe9rHL4V .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WIOujDuAWe9rHL4V .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WIOujDuAWe9rHL4V .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WIOujDuAWe9rHL4V .marker.cross{stroke:#333333;}#mermaid-svg-WIOujDuAWe9rHL4V svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WIOujDuAWe9rHL4V .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-WIOujDuAWe9rHL4V text.actortspan{fill:black;stroke:none;}#mermaid-svg-WIOujDuAWe9rHL4V .actor-line{stroke:grey;}#mermaid-svg-WIOujDuAWe9rHL4V .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-WIOujDuAWe9rHL4V .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-WIOujDuAWe9rHL4V #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-WIOujDuAWe9rHL4V .sequenceNumber{fill:white;}#mermaid-svg-WIOujDuAWe9rHL4V #sequencenumber{fill:#333;}#mermaid-svg-WIOujDuAWe9rHL4V #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-WIOujDuAWe9rHL4V .messageText{fill:#333;stroke:#333;}#mermaid-svg-WIOujDuAWe9rHL4V .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-WIOujDuAWe9rHL4V .labelText,#mermaid-svg-WIOujDuAWe9rHL4V .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-WIOujDuAWe9rHL4V .loopText,#mermaid-svg-WIOujDuAWe9rHL4V .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-WIOujDuAWe9rHL4V .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-WIOujDuAWe9rHL4V .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-WIOujDuAWe9rHL4V .noteText,#mermaid-svg-WIOujDuAWe9rHL4V .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-WIOujDuAWe9rHL4V .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-WIOujDuAWe9rHL4V .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-WIOujDuAWe9rHL4V .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-WIOujDuAWe9rHL4V .actorPopupMenu{position:absolute;}#mermaid-svg-WIOujDuAWe9rHL4V .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-WIOujDuAWe9rHL4V .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-WIOujDuAWe9rHL4V .actor-man circle,#mermaid-svg-WIOujDuAWe9rHL4V line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-WIOujDuAWe9rHL4V :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} A loveValue B increaseLove / decreaseLove increaseLove / decreaseLove A loveValue B Bug 示意图 1.3 Bug 解决
解决这个问题就得用到一个更为精细的同步机制以允许线程 A 和 B 在不互相阻塞的情况下更新 loveValue。我们可以使用条件变量使得线程 A 和 B 可以在适当的时机等待和唤醒。
#include iostream
#include thread
#include mutex
#include condition_variablestd::mutex loveMutex;
std::condition_variable loveCV;
int loveValue 50;
bool isIncreasing true;void increaseLove(int amount) {std::lock_guardstd::mutex lock(loveMutex);loveValue amount;isIncreasing true;loveCV.notify_one();
}void decreaseLove(int amount) {std::unique_lockstd::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) x16⋅sin3(t),y13⋅cos(t)−5⋅cos(2t)−2⋅cos(3t)−cos(4t) 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 A21∫02πy(t)⋅x′(t)dt
1.2 Bug 分析
1.2.1 初始代码
代码如下
#include iostream
#include cmathconst 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 代码工作流程图 #mermaid-svg-IgRtvkyo3PrTUNce {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-IgRtvkyo3PrTUNce .error-icon{fill:#552222;}#mermaid-svg-IgRtvkyo3PrTUNce .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IgRtvkyo3PrTUNce .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-IgRtvkyo3PrTUNce .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IgRtvkyo3PrTUNce .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IgRtvkyo3PrTUNce .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IgRtvkyo3PrTUNce .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IgRtvkyo3PrTUNce .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IgRtvkyo3PrTUNce .marker.cross{stroke:#333333;}#mermaid-svg-IgRtvkyo3PrTUNce svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IgRtvkyo3PrTUNce .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IgRtvkyo3PrTUNce text.actortspan{fill:black;stroke:none;}#mermaid-svg-IgRtvkyo3PrTUNce .actor-line{stroke:grey;}#mermaid-svg-IgRtvkyo3PrTUNce .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-IgRtvkyo3PrTUNce .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-IgRtvkyo3PrTUNce #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-IgRtvkyo3PrTUNce .sequenceNumber{fill:white;}#mermaid-svg-IgRtvkyo3PrTUNce #sequencenumber{fill:#333;}#mermaid-svg-IgRtvkyo3PrTUNce #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-IgRtvkyo3PrTUNce .messageText{fill:#333;stroke:#333;}#mermaid-svg-IgRtvkyo3PrTUNce .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IgRtvkyo3PrTUNce .labelText,#mermaid-svg-IgRtvkyo3PrTUNce .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-IgRtvkyo3PrTUNce .loopText,#mermaid-svg-IgRtvkyo3PrTUNce .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-IgRtvkyo3PrTUNce .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-IgRtvkyo3PrTUNce .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-IgRtvkyo3PrTUNce .noteText,#mermaid-svg-IgRtvkyo3PrTUNce .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-IgRtvkyo3PrTUNce .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IgRtvkyo3PrTUNce .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IgRtvkyo3PrTUNce .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IgRtvkyo3PrTUNce .actorPopupMenu{position:absolute;}#mermaid-svg-IgRtvkyo3PrTUNce .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-IgRtvkyo3PrTUNce .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IgRtvkyo3PrTUNce .actor-man circle,#mermaid-svg-IgRtvkyo3PrTUNce line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-IgRtvkyo3PrTUNce :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 初始代码 修复后代码 计算参数方程 初始代码数值积分计算 修复后代码数值积分计算 初始代码输出结果 修复后代码输出结果 调用 调用 返回结果 返回结果 调用 调用 提供参数 提供参数 返回结果 返回结果 初始代码 修复后代码 计算参数方程 初始代码数值积分计算 修复后代码数值积分计算 初始代码输出结果 修复后代码输出结果 理想的代码工作流程图 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(ai⋅h)y(a(i1)⋅h))/2.0 (y(ai⋅h)y(a(i1)⋅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(th) x(th) 分别作为小区间的左边界和右边界并使用中点的 y y y 值乘以小区间的宽度来计算近似的面积。这个修正考虑了 x ′ ( t ) x′(t) x′(t) 的影响使得程序能够更准确地计算心形曲线所围成的区域面积。
三、总结
Bug 1: 多线程环境中的同步问题
这个Bug发生在一个涉及多线程的环境中。通过竞争访问一个共享变量在代码中模拟了两位恋人之间的爱情值互动。尽管看起来没有问题但实际上由于同步机制的缺失线程 A 和 B 之间的爱情互动被锁定无法正常交替进行导致无法真实感受到彼此的情感。通过重新设计同步机制我们解决了这个问题使得线程 A 和 B 能够在不互相阻塞的情况下更新爱情值实现了恋人之间情感的自由流动。
Bug 2: 心形函数面积计算错误
这个Bug涉及到计算心形函数所围成的区域面积。初始代码使用矩形法计算数值积分来近似区域面积但在计算过程中忽略了心形曲线的导数。因此计算得到的区域面积并不准确。通过引入导数修正我们重新计算每个小段的面积考虑了函数的变化率从而得到了更精确的区域面积。这个修复展示了数学模型与代码之间的相互作用揭示了在复杂问题中精确建模的重要性。
附录心形函数代码
import numpy as np
import matplotlib.pyplot as plt# 心形的参数方程
def x(t):return 16 * np.sin(t)**3def 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, colorred)
plt.title(Heart Shape Function)
plt.xlabel(x)
plt.ylabel(y)
plt.grid(True)
plt.axis(equal) # x轴和y轴的相等纵横比
plt.show()