当前位置: 首页 > 后端技术 > Python

为什么浮点运算会产生错误

时间:2023-03-26 12:20:40 Python

鍓嶈█姣忎釜浜哄湪鍐欎唬鐮佺殑鏃跺€欓兘浼氶亣鍒版墍璋撶殑娴偣閿欒銆傚鏋滀綘娌℃湁韪╄繃娴偣鏁伴敊璇殑鍧戯紝鍙兘璇翠綘澶垢杩愪簡銆備互涓嬪浘涓殑Python涓轰緥锛?.1+0.2涓嶇瓑浜?.3锛?.7/10涓嶇瓑浜?.87锛岃€屾槸0.869999...锛岃繖鐪熺殑寰堝鎬煠斾絾杩欑粷瀵逛笉鏄湴鐙眀ug锛孭ython鐨勮璁′篃娌℃湁闂锛屼絾鏄畠鏄诞鐐规暟鍦ㄥ仛璁$畻鏃剁殑蹇呯劧缁撴灉锛屾墍浠ュ嵆浣挎槸JavaScript鎴栬€呭叾浠栬瑷€涔熸槸涓€鏍风殑锛氳绠楁満濡備綍瀛樺偍涓€涓暣鏁帮紙Integer锛変箣鍓嶈鐨勫叧浜庝负浠€涔堜細鍑虹幇娴偣鏁伴敊璇紝涓嬮潰璇磋璁$畻鏈哄浣曠敤0鍜?琛ㄧず鏁存暟锛屼簩杩涘埗澶у搴旇閮界煡閬擄細姣斿101琛ㄧず$2^2+2^0$涔熷氨鏄?锛?010琛ㄧず$2^3+2^1$鍗?0锛屽鏋滄槸鏃犵鍙风殑32浣嶆暣鏁帮紝鍒欒〃绀哄畠鏈?2涓綅缃彲浠ユ斁0鎴?锛屾墍浠ユ渶灏忓€间负0000...0000鍗?锛岃€屾渶澶у€?111...1111琛ㄧず$2^{31}+2^{30}+...+2^1+2^0$涓?294967295浠庢帓鍒楃粍鍚堢殑瑙掑害鏉ョ湅锛屽洜涓烘瘡涓猙it鍙互鏄?涔熷彲浠ユ槸1锛屾暣涓彉閲忕殑鍊奸兘鏄?2^{32}$閮芥槸鍙互鐨勶紝鎵€浠?鍒?2^{23}-1$涔嬮棿鐨勪换浣曞€奸兘鍙互鍑嗙‘琛ㄨ揪锛屼笉浼氭湁浠讳綍閿欒銆傝櫧鐒朵粠0鍒?2^{23}-1$鐨勬暣鏁版湁寰堝锛屼絾鏄诞鐐规暟鐨勪釜鏁版槸鏈夐檺鐨勶紝涔熷氨鏄彧鏈?2^{32}$閭d箞澶氾紱浣嗘槸娴偣鏁板氨涓嶄竴鏍蜂簡锛屾垜浠彲浠ヨ繖鏍锋兂锛氫粠1鍒?0鐨勫尯闂村彧鏈夊崄涓暣鏁帮紝浣嗘槸娴偣鏁板嵈鏈夋棤绌峰涓紝姣斿5.1銆?.11銆?.111绛夛紝娓呭崟涓嶈兘绌峰敖銆備絾鏄洜涓?2浣嶇┖闂村彧鏈?鲁虏鐨勫彲鑳斤紝涓轰簡鎶婃墍鏈夌殑娴偣鏁伴兘濉炶繘杩欎釜32浣嶇┖闂达紝寰堝CPU鍘傚晢鍙戞槑浜嗗悇绉嶆诞鐐规暟鐨勮〃绀烘柟寮忥紝浣嗘槸濡傛灉姣忎竴涓殑鏍煎紡CPU涓嶄竴鏍峰緢楹荤儲锛屾墍浠ユ渶鍚庤繕鏄噰鐢ㄤ簡IEEE鍙戝竷鐨処EEE754浣滀负娴偣杩愮畻鐨勯€氱敤鏍囧噯锛岀幇鍦ㄧ殑CPU涔熸槸鎸夌収杩欎釜鏍囧噯璁捐鐨勩€侷EEE754IEEE754瀹氫箟浜嗗緢澶氫笢瑗匡紝鍖呮嫭鍗曠簿搴︼紙32浣嶏級銆佸弻绮惧害锛?4浣嶏級鍜岀壒娈婂€硷紙鏃犵┓澶с€丯aN锛夌瓑鐨勮〃绀恒€傚浜庢诞鐐规暟8.5锛屽鏋滆鏀规垚IEEE754鏍煎紡鐨勮瘽锛屽繀椤诲厛鍋氫竴浜涘綊涓€鍖栧鐞嗭細灏?.5鎷嗘垚8+0.5锛屽嵆$2^3+(\cfrac{1}{2})^1$锛岀劧鍚庡啓鎴愪簩杩涘埗鍙樻垚1000.1锛屾渶鍚庡啓鎴?1.0001\times2^3$锛屽緢鍍忓崄杩涘埗鐨勭瀛﹁鏁版硶銆傚湪IEEE754涓紝鍗曠簿搴︽诞鐐规暟鏄皢32浣嶆诞鐐规暟鎷嗗垎涓虹鍙枫€佹寚鏁板拰鍒嗘暟涓夐儴鍒嗭紝瀹冧滑鍔犺捣鏉ヤ竴鍏辨槸32浣嶇鍙凤紙sign锛夛細鏈€宸﹁竟1浣嶄唬琛ㄦ璐熷彿銆傚鏋滄暟涓烘鏁帮紝鍒欑鍙蜂负0锛屽惁鍒欎负1闃剁爜锛堟寚鏁帮級锛氫腑闂?浣嶈〃绀哄綊涓€鍖栧悗鐨勫箓锛屾寚鏁颁负鐪熷€?127鐨勬牸寮忥紝鍗?鍔犱笂127绛変簬130鐨勫熬鏁帮紙鍒嗘暟锛夛細鏈€鍙宠竟鐨?3浣嶆槸灏忔暟閮ㄥ垎锛屽湪1.0001鐨勬儏鍐典笅鍘绘帀1鍚庨潰鐨?001锛屾墍浠ュ鏋滆〃绀?.5鐨勮瘽鏄?2浣嶆牸寮忕殑璇濓紝搴旇鏄繖鏍风殑锛氫粈涔堟儏鍐典笅浼氬嚭閿欙紵鍓嶉潰8.5鐨勪緥瀛愬彲浠ヨ〃绀轰负$2^3+(\cfrac{1}{2})^1$锛屽洜涓?鍜?.5閮芥槸2鐨勫箓锛屾墍浠ュ畬鍏ㄤ笉浼氭湁绮惧害闂銆備絾鏄鏋滄槸8.9锛屽洜涓烘病鏈夊姙娉曞姞涓?鐨勬鏂癸紝鎵€浠ヤ細寮哄埗琛ㄧず涓?1.0001110011...\times2^3$锛屼細鍑虹幇$0.0000003$宸﹀彸鐨勮宸€傚鏋滄偍瀵圭粨鏋滄劅鍒板ソ濂囷紝鍙互璁块棶IEEE-754FloatingPointConverter缃戠珯骞跺皾璇曚竴涓嬨€傚弻绮惧害娴偣鏁颁笂闈㈡彁鍒扮殑鍗曠簿搴︽诞鐐规暟鍙敤32浣嶆潵琛ㄧず銆備负浜嗕娇璇樊鏇村皬锛孖EEE754杩樺畾涔変簡濡備綍浣跨敤64浣嶆潵琛ㄧず娴偣鏁般€備笌32浣嶇浉姣旓紝灏忔暟閮ㄥ垎鎵╁ぇ浜嗕袱浣嶃€傛锛屼粠23浣嶅埌52浣嶏紝閭d箞鍑嗙‘鐜囪嚜鐒朵細鎻愰珮寰堝銆備互鍒氭墠鐨?.9涓轰緥锛岃櫧鐒跺鏋滅敤64浣嶈〃绀哄彲浠ユ洿鍑嗙‘锛屼絾鏄敱浜?.9涓嶈兘瀹屽叏鍐欐垚2鐨勫箓鐩稿姞锛屾墍浠ュ埌浜嗗皬鏁扮偣鍚?6浣嶈繕鏄細鍑虹幇閿欒锛屼絾鏄笌鍗曠簿搴︾殑璇樊涓?.0000003鐩告瘮锛岃灏忓緢澶氥€傜被浼肩殑鎯呭喌涓嬶紝Python涓殑1.0绛変簬0.999...999锛?23绛変簬122.999...999锛屽洜涓哄畠浠箣闂寸殑宸窛澶皬浜嗭紝涓嶈兘鏀惧湪灏忔暟閲岄潰锛屾墍浠ヤ粠浜岃繘鍒舵牸寮忕湅浼间箮鏄粬浠殑姣忎竴鐐归兘鏄竴鏍风殑銆傝В鍐虫柟妗堢敱浜庢诞鐐规暟鐨勯敊璇槸涓嶅彲閬垮厤鐨勶紝鎴戜滑涓嶅緱涓嶅繊鍙楀畠銆備笅闈㈡槸涓ょ甯歌鐨勫鐞嗘柟寮忥細璁剧疆鏈€澶у厑璁歌宸碉紙epsilon锛夋湁浜涜瑷€浼氭彁渚涙墍璋撶殑epsilon锛岀敤鏉ヨ浣犲垽鏂槸鍚﹀湪娴偣鏁拌宸厑璁歌寖鍥村唴锛孭ython涓璭psilon鐨勫€肩害涓?2.2e^{-16}$鎵€浠ュ彲浠ュ皢0.1+0.2==0.3鏀瑰啓涓?.1+0.2鈥?.3<=epsilon锛岃繖鏍峰氨鍙互閬垮厤娴偣鏁伴敊璇湪杩愮畻涓€犳垚楹荤儲锛屽苟涓斿彲浠ユ纭瘮杈?.1鍔?.2鏄惁绛変簬0.3銆傚綋鐒讹紝濡傛灉绯荤粺娌℃湁鎻愪緵锛屼綘涔熷彲浠ヨ嚜宸卞畾涔変竴涓猠psilon锛岃缃湪2鐨?15娆℃柟宸﹀彸銆傚皬鏁伴儴鍒嗗叏閮ㄥ鍏ュ熬鏁般€傜敱浜庤浆鎹㈡椂鍙兘鏈夐敊璇紝骞茶剢涓嶈浆鎹紝鐩存帴鐢ㄥ崄杩涘埗璁$畻銆傚湪Python涓湁涓€涓悕涓篸ecimal鐨勬ā鍧楋紝鍦↗avaScript涓湁涓€涓被浼肩殑鍖呫€傚畠鍙互甯綘璁$畻鍗佽繘鍒讹紝灏卞儚浣犲彲浠ョ敤绗斿拰绾歌绠?.1+0.2涓€鏍凤紝缁濆涓嶄細鍑洪敊锛屼笉浼氬嚭閿欍€傝櫧鐒朵娇鐢ㄥ崄杩涘埗璁$畻鍙互瀹屽叏閬垮厤娴偣鏁伴敊璇紝浣嗘槸鐢变簬Decimal鐨勫崄杩涘埗璁$畻鏄ā鎷熺殑锛屾墍浠ュ湪鏈€搴曞眰鐨凜PU鐢佃矾涓粛鐒朵娇鐢ㄤ簩杩涘埗璁$畻锛屾墽琛岄€熷害浼氭瘮鍘熺敓鐨勬诞鐐硅绠楁參寰堝銆傛墍浠ヤ笉寤鸿瀵规墍鏈夋诞鐐硅繍绠楅兘浣跨敤Decimal銆?/p>