97色伦色在线综合视频,无玛专区,18videosex性欧美黑色,日韩黄色电影免费在线观看,国产精品伦理一区二区三区,在线视频欧美日韩,亚洲欧美在线中文字幕不卡

什么網(wǎng)站做電子元器件最好看免費視頻

鶴壁市浩天電氣有限公司 2026/01/24 15:44:17
什么網(wǎng)站做電子元器件,最好看免費視頻,雄安投資建設(shè)集團有限公司網(wǎng)站,電子科技網(wǎng)站模板浮點數(shù)的本質(zhì)#xff1a;為什么計算機無法精確表示0.1 當你在 C 中寫下 float x 0.1; 時#xff0c;你以為計算機存儲的就是精確的 0.1。但事實是#xff0c;計算機存儲的是一個非常接近 0.1 的近似值。這不是編譯器的缺陷#xff0c;也不是硬件的問題#xff0c;而是浮點…浮點數(shù)的本質(zhì)為什么計算機無法精確表示0.1當你在 C 中寫下float x 0.1;時你以為計算機存儲的就是精確的 0.1。但事實是計算機存儲的是一個非常接近 0.1 的近似值。這不是編譯器的缺陷也不是硬件的問題而是浮點數(shù)表示機制的必然結(jié)果。理解這個機制是理解所有數(shù)值計算問題的起點。問題的起源有限的 bit 如何表示無限的實數(shù)計算機只能處理 0 和 1。整數(shù)容易表示因為它們本身就可以精確地轉(zhuǎn)換為二進制。但實數(shù)是連續(xù)的它們在數(shù)軸上密密麻麻地分布著而我們只有有限個 bit 可以使用。這就像用有限個標記點去標識一條無限延伸的直線必然會有大量的數(shù)值無法被精確標記。更具體地說當我們用 32 個 bit 來表示浮點數(shù)時我們只能表示 2^32 約等于 42 億個不同的數(shù)值。而實數(shù)有無窮多個即使只考慮 0 到 1 之間的實數(shù)也有無窮多個。這意味著絕大多數(shù)實數(shù)根本無法被精確表示計算機只能選擇最接近的那個可表示的值。這就是浮點數(shù)表示的根本困境用有限的編碼空間去逼近無限的數(shù)值空間。IEEE 754 標準定義的浮點數(shù)格式就是在這個約束下做出的最優(yōu)工程設(shè)計。浮點數(shù)的表示二進制科學計數(shù)法計算機采用的解決方案是二進制科學計數(shù)法。在十進制中我們寫 1.23 × 10^4 來表示 12300這樣可以用較少的位數(shù)表示較大范圍的數(shù)值。浮點數(shù)也采用了同樣的思路只不過基數(shù)是 2 而不是 10。以 C 中的float類型為例它占用 32 個 bit被劃分為三個部分。第一個 bit 是符號位決定這個數(shù)是正是負。接下來的 8 個 bit 是指數(shù)位決定這個數(shù)的量級大小。最后的 23 個 bit 是尾數(shù)位決定這個數(shù)的精確度。這個設(shè)計的數(shù)學形式是(-1)^s × 2^(e-127) × (1.f)其中 s 是符號位e 是指數(shù)位的值f 是尾數(shù)位表示的小數(shù)部分。這里有兩個關(guān)鍵細節(jié)。第一指數(shù)位存儲的是 e但實際使用時要減去 127這個 127 叫做偏置值。第二尾數(shù)部分的整數(shù)位永遠是 1所以不需要存儲只存儲小數(shù)部分這叫做隱式前導(dǎo)位。讓我們看一個具體例子。數(shù)值 2.5 在二進制中是 10.1寫成規(guī)格化的科學計數(shù)法是 1.01 × 2^1。符號位是 0 表示正數(shù)指數(shù)是 1 但存儲時要加上偏置 127 得到 128尾數(shù)是 01 后面補 21 個零。這樣2.5 就被精確地編碼進了 32 個 bit 中。我們可以用代碼驗證這一點/* by 01022.hk - online tools website : 01022.hk/zh/json2excel.html */ #include iostream #include cstring #include bitset int main() { float x 2.5f; // 將 float 的內(nèi)存表示解釋為整數(shù) uint32_t bits; std::memcpy(bits, x, sizeof(float)); // 輸出二進制表示 std::cout 2.5 的二進制表示: std::bitset32(bits) std::endl; // 輸出: 01000000001000000000000000000000 // ^符號 ^指數(shù)(128) ^尾數(shù)(01后面全是0) std::cout 實際存儲的值: x std::endl; // 輸出: 2.5 (精確) return 0; }在這個例子中2.5 被完美地表示出來因為它在二進制中恰好是有限小數(shù)。第一個困難二進制無法精確表示的十進制小數(shù)現(xiàn)在我們遇到了第一個問題。2.5 可以被精確表示因為它在二進制中是有限小數(shù) 10.1。但 0.1 就不行了。當你嘗試把十進制的 0.1 轉(zhuǎn)換成二進制時你會得到一個無限循環(huán)的二進制小數(shù)0.0001100110011...這個 0011 的循環(huán)永遠不會停止。這和十進制中 1/3 0.333... 無法精確表示是同樣的道理只不過在二進制中更多看起來簡單的十進制小數(shù)都變成了無限循環(huán)小數(shù)。0.1、0.2、0.3 這些我們?nèi)粘J褂玫臄?shù)值在二進制中都無法精確表示。當你寫float x 0.1;時計算機會找到最接近 0.1 的那個可表示的浮點數(shù)。這個數(shù)非常接近 0.1但不是精確的 0.1。這就是為什么你會在數(shù)值計算中看到 0.1 0.2 不等于 0.3 的現(xiàn)象因為這三個數(shù)在存儲時都已經(jīng)是近似值了。讓我們用代碼直觀地看到這個問題/* by 01022.hk - online tools website : 01022.hk/zh/json2excel.html */ #include iostream #include iomanip int main() { float a 0.1f; float b 0.2f; float c 0.3f; // 設(shè)置高精度輸出 std::cout std::setprecision(20); std::cout a a std::endl; // 輸出: 0.10000000149011611938 std::cout b b std::endl; // 輸出: 0.20000000298023223877 std::cout c c std::endl; // 輸出: 0.30000001192092895508 std::cout a b (a b) std::endl; // 輸出: 0.30000000447034835815 std::cout a b c: (a b c ? true : false) std::endl; // 輸出: false return 0; }這段代碼清楚地展示了問題的本質(zhì)。0.1 在計算機中實際存儲的是 0.100000001...0.2 存儲的是 0.200000002...它們的和自然不會等于存儲的 0.3。這不是 bug而是二進制表示的必然結(jié)果。正確的比較方法應(yīng)該是判斷差值是否足夠小#include iostream #include cmath int main() { float a 0.1f; float b 0.2f; float c 0.3f; const float epsilon 1e-6f; // 容差閾值 if (std::abs((a b) - c) epsilon) { std::cout 在容差范圍內(nèi)相等 std::endl; } else { std::cout 不相等 std::endl; } return 0; }第二個困難尾數(shù)位數(shù)限制帶來的精度損失即使一個數(shù)在二進制中可以表示為有限小數(shù)如果它需要的有效數(shù)字超過了 23 位尾數(shù)所能容納的范圍也會發(fā)生精度損失??紤]一個很大的整數(shù)比如 16777217。這個數(shù)在二進制中是 1 后面跟 24 個 bit。要用科學計數(shù)法表示它我們需要 24 位有效數(shù)字但float的尾數(shù)只有 23 位。計算機必須舍棄最后一位存儲的實際上是 16777216。這意味著float類型最多只能精確表示大約 7 位十進制有效數(shù)字。超過這個精度的數(shù)值無論你寫得多么精確存儲時都會被四舍五入到最近的可表示值。這就是為什么在金融計算或科學計算中我們經(jīng)常需要使用double類型它有 53 位尾數(shù)可以提供大約 15 位十進制有效數(shù)字的精度。讓我們用代碼展示精度損失的問題#include iostream #include iomanip int main() { // float 的精度極限 float f1 16777216.0f; // 2^24剛好可以精確表示 float f2 16777217.0f; // 2^24 1超出精度 std::cout std::setprecision(10); std::cout f1 f1 std::endl; // 輸出: 16777216 std::cout f2 f2 std::endl; // 輸出: 16777216 (注意不是 16777217) std::cout f1 f2: (f1 f2 ? true : false) std::endl; // 輸出: true (兩個不同的數(shù)變成了同一個值) // 大數(shù)加小數(shù)的精度丟失 float big 1e8f; float small 1.0f; float result big small; std::cout 大數(shù)加小數(shù): std::endl; std::cout big big std::endl; std::cout result result std::endl; std::cout big result: (big result ? true : false) std::endl; // 輸出: true (小數(shù)完全被淹沒) // 對比 double 的表現(xiàn) double d1 16777216.0; double d2 16777217.0; std::cout double 的表現(xiàn): std::endl; std::cout d1 d1 std::endl; std::cout d2 d2 std::endl; std::cout d1 d2: (d1 d2 ? true : false) std::endl; // 輸出: false (double 可以區(qū)分這兩個數(shù)) return 0; }這段代碼清楚地展示了float的精度限制。當數(shù)值超過一定范圍時連相鄰的整數(shù)都無法區(qū)分。而在大數(shù)加小數(shù)的場景中小數(shù)會被完全忽略這在累加計算中是非常危險的。范圍的極限從最大數(shù)到無窮浮點數(shù)不僅有精度限制還有范圍限制。指數(shù)位決定了數(shù)值的量級范圍。對于float8 位指數(shù)理論上可以表示 0 到 255但 IEEE 754 標準保留了兩個特殊值全零和全一。當指數(shù)位是全零時表示的是非常接近零的非規(guī)格化數(shù)。當指數(shù)位是全一時表示的是特殊值。因此正常的指數(shù)范圍是 1 到 254減去偏置 127 后真實指數(shù)范圍是 -126 到 127。最大的正常浮點數(shù)出現(xiàn)在指數(shù)是 127 且尾數(shù)全為 1 的情況。此時尾數(shù)部分 1.f 接近但小于 2所以最大的float大約是 2 × 2^127約等于 3.4 × 10^38。這是一個非常大的數(shù)但它仍然是有限的。當計算結(jié)果超過這個最大值時會發(fā)生什么答案是溢出。IEEE 754 標準規(guī)定上溢的結(jié)果不是報錯而是返回一個特殊值正無窮或負無窮。讓我們用代碼觀察溢出的發(fā)生#include iostream #include limits #include cmath int main() { // 查看 float 的最大值 float max_float std::numeric_limitsfloat::max(); std::cout float 的最大值: max_float std::endl; // 輸出: 3.40282e38 // 制造溢出 float x max_float; float y x * 2.0f; std::cout max_float * 2 y std::endl; // 輸出: inf std::cout 是否為無窮: (std::isinf(y) ? true : false) std::endl; // 輸出: true // 另一種觸發(fā)方式 float a 1e38f; float b a * 10.0f; std::cout 1e38 * 10 b std::endl; // 輸出: inf // 正無窮和負無窮 float pos_inf std::numeric_limitsfloat::infinity(); float neg_inf -std::numeric_limitsfloat::infinity(); std::cout 正無窮: pos_inf std::endl; std::cout 負無窮: neg_inf std::endl; // 無窮的運算特性 std::cout inf 1 (pos_inf 1.0f) std::endl; // 輸出: inf std::cout inf * 2 (pos_inf * 2.0f) std::endl; // 輸出: inf std::cout inf 任何有限數(shù): (pos_inf max_float ? true : false) std::endl; // 輸出: true return 0; }這段代碼展示了無窮的產(chǎn)生和性質(zhì)。需要強調(diào)的是這里的 inf 不是數(shù)學意義上的無窮大而是一個編碼約定表示數(shù)值超出了浮點數(shù)的表示范圍。它的指數(shù)位是全一尾數(shù)位是全零。不確定性的表達NaN 的存在除了無窮還有一類更特殊的值NaN意思是 Not a Number。當一個運算在數(shù)學上沒有定義時結(jié)果就是 NaN。最典型的例子是零除以零。但觸發(fā) NaN 的情況遠不止這一種。負數(shù)的平方根、無窮減去無窮、無窮除以無窮這些在數(shù)學上沒有確定結(jié)果的運算都會產(chǎn)生 NaN。NaN 的編碼方式是指數(shù)位全為一但尾數(shù)位不為零。這和 inf 形成了對比同樣是指數(shù)全一但通過尾數(shù)是否為零來區(qū)分方向明確的發(fā)散和完全無定義的狀態(tài)。NaN 有一個非常反直覺的性質(zhì)它不等于任何值包括它自己。在 C 中x x的結(jié)果可以是 false當且僅當 x 是 NaN 時。這不是語言設(shè)計的失誤而是 IEEE 754 標準的明確規(guī)定因為 NaN 代表的不是一個數(shù)值點而是一個未定義的狀態(tài)。讓我們用代碼觀察 NaN 的行為#include iostream #include cmath #include limits int main() { // 產(chǎn)生 NaN 的幾種方式 float nan1 0.0f / 0.0f; float nan2 std::sqrt(-1.0f); float nan3 std::numeric_limitsfloat::infinity() - std::numeric_limitsfloat::infinity(); float nan4 std::numeric_limitsfloat::infinity() / std::numeric_limitsfloat::infinity(); std::cout 0.0 / 0.0 nan1 std::endl; std::cout sqrt(-1) nan2 std::endl; std::cout inf - inf nan3 std::endl; std::cout inf / inf nan4 std::endl; // 輸出都是: nan // NaN 的反直覺特性 float x std::nanf(); std::cout NaN 的比較特性: std::endl; std::cout NaN NaN: (x x ? true : false) std::endl; // 輸出: false (唯一一個不等于自己的值) std::cout NaN ! NaN: (x ! x ? true : false) std::endl; // 輸出: true std::cout NaN 0: (x 0.0f ? true : false) std::endl; // 輸出: false std::cout NaN 0: (x 0.0f ? true : false) std::endl; // 輸出: false std::cout NaN 0: (x 0.0f ? true : false) std::endl; // 輸出: false // 檢測 NaN 的正確方法 std::cout 檢測 NaN: std::endl; std::cout 使用 std::isnan: (std::isnan(x) ? true : false) std::endl; // 輸出: true // NaN 的傳播性 float result 1.0f x; std::cout 1.0 NaN result std::endl; // 輸出: nan std::cout 是否為 NaN: (std::isnan(result) ? true : false) std::endl; // 輸出: true (NaN 會傳播到所有涉及它的運算) return 0; }這段代碼充分展示了 NaN 的特殊性質(zhì)。特別要注意的是NaN 不參與正常的數(shù)值比較任何涉及 NaN 的比較都返回 false。這就是為什么我們不能用x x來判斷一個數(shù)是否正常而應(yīng)該使用std::isnan(x)函數(shù)。實踐中的啟示理解了浮點數(shù)的底層表示機制后我們可以得出幾個重要的實踐原則。第一永遠不要用等號比較兩個浮點數(shù)。由于表示誤差和計算誤差的累積兩個理論上應(yīng)該相等的浮點數(shù)在計算機中可能略有差異。正確的做法是判斷它們的差的絕對值是否小于一個很小的閾值。第二在進行大量浮點運算時要注意誤差累積。每次運算都可能引入微小的誤差這些誤差會累積。特別是在求和時如果數(shù)值的量級相差很大小數(shù)值可能會被完全淹沒。讓我們用一個實際例子說明誤差累積的危險#include iostream #include iomanip int main() { std::cout std::setprecision(10); // 錯誤的累加方式直接累加小數(shù) float sum1 0.0f; for (int i 0; i 10000000; i) { sum1 0.1f; } std::cout 直接累加 0.1 一千萬次: sum1 std::endl; std::cout 理論值應(yīng)該是: 1000000.0f std::endl; std::cout 誤差: (1000000.0f - sum1) std::endl; // 誤差可能達到幾百甚至上千 // 大數(shù)加小數(shù)的問題 float big 1e8f; float small_sum 0.0f; for (int i 0; i 1000; i) { small_sum 1.0f; } float result big small_sum; std::cout 1e8 (1000個1的和) result std::endl; std::cout 是否等于 1e8: (result big ? true : false) std::endl; // 可能輸出 true小數(shù)完全丟失 return 0; }第三在需要高精度的場景中要選擇合適的數(shù)據(jù)類型。如果float的 7 位有效數(shù)字不夠就使用double的 15 位。如果連double都不夠可能需要考慮使用高精度數(shù)值庫。第四在寫浮點字面量時建議明確標記類型。10f明確表示這是一個float而10.0默認是double。這不僅避免了不必要的類型轉(zhuǎn)換也讓代碼的意圖更加清晰。#include iostream int main() { // 推薦的寫法明確類型 float x 10.0f; // float 字面量 double y 10.0; // double 字面量 // 不推薦的寫法隱式轉(zhuǎn)換 float z 10.0; // double 轉(zhuǎn) float可能有警告 // 科學計數(shù)法的寫法 float a 1.5e-3f; // 0.0015 double b 1.5e-3; // 0.0015 return 0; }總結(jié)浮點數(shù)不能精確表示所有實數(shù)這不是缺陷而是在有限資源下必然的權(quán)衡。計算機用 32 個或 64 個 bit在精度、范圍和計算效率之間找到了一個平衡點。理解這個平衡點就會理解為什么 0.1 0.2 不等于 0.3為什么大數(shù)加小數(shù)會丟失精度為什么會出現(xiàn) inf 和 NaN。
版權(quán)聲明: 本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請聯(lián)系我們進行投訴反饋,一經(jīng)查實,立即刪除!

什么網(wǎng)站做電子元器件最好看免費視頻

什么網(wǎng)站做電子元器件,最好看免費視頻,雄安投資建設(shè)集團有限公司網(wǎng)站,電子科技網(wǎng)站模板浮點數(shù)的本質(zhì)#xff1a;為什么計算機無法精確表示0.1 當你在 C 中寫下 float x 0.1; 時#xff

2026/01/23 18:31:01

個人制作的網(wǎng)站模板wordpress vue

個人制作的網(wǎng)站模板,wordpress vue,網(wǎng)站被k的怎么辦,平面廣告設(shè)計案例分析面向中小學的AI通識課程完整教學指南 【免費下載鏈接】ai-edu-for-kids 面向中小學的人工智能通識課開

2026/01/21 17:14:01

怎么提高網(wǎng)站曝光2023熱點新聞事件

怎么提高網(wǎng)站曝光,2023熱點新聞事件,咋做網(wǎng)站代碼背景圖,做網(wǎng)站顏色類型是啥TensorFlow 與容器化開發(fā)#xff1a;構(gòu)建高效 AI 研發(fā)環(huán)境的現(xiàn)代實踐 在人工智能技術(shù)快速滲透各行各業(yè)的今天#

2026/01/23 16:01:01