RND指令執(zhí)行出錯(cuò)的原因分析

發(fā)布時(shí)間:2024-02-19
網(wǎng)友ktissot在用下面3條指令將浮點(diǎn)數(shù)轉(zhuǎn)換為雙整數(shù)時(shí),發(fā)現(xiàn)了一個(gè)神秘的現(xiàn)象。
l md0
rnd //浮點(diǎn)數(shù)四舍五入
t md4
我們知道,最大的正的雙整數(shù)是2147483647,大于這個(gè)數(shù),rnd指令轉(zhuǎn)換會(huì)出錯(cuò)。
但是他的帖子說實(shí)際上能轉(zhuǎn)換的最大的浮點(diǎn)數(shù)不是2147483647.0,而是2147483583.0。
這一段本應(yīng)正常轉(zhuǎn)換的區(qū)間轉(zhuǎn)換會(huì)出錯(cuò),為什么轉(zhuǎn)換出錯(cuò)的分界點(diǎn)是2147483583.0,這里面隱藏了什么秘密?
這件事引起我極大的興趣,為此我用仿真做了大量的實(shí)驗(yàn),下面是我做實(shí)驗(yàn)發(fā)現(xiàn)的更多的現(xiàn)象:
1.轉(zhuǎn)換出錯(cuò)的情況
rnd指令的幫助中說:“如果超出允許范圍,則狀態(tài)位ov和os被置位為1。結(jié)果存在累加器1中”?!俺霈F(xiàn)錯(cuò)誤(使用了不能表示為32位整數(shù)的nan或浮點(diǎn)數(shù))時(shí)不執(zhí)行轉(zhuǎn)換并顯示溢出?!薄?br>下圖用程序狀態(tài)監(jiān)控狀態(tài)字status word。
大于2147483647.0時(shí)轉(zhuǎn)換出錯(cuò)。
大于2147483584.0到2147483647.0這一段照理說在應(yīng)該在能轉(zhuǎn)換的范圍里,但是轉(zhuǎn)換也會(huì)出錯(cuò),狀態(tài)字的ov和os位(第4、5位)被置位為1(見下圖)。md4中是沒有轉(zhuǎn)換的浮點(diǎn)數(shù),而不是雙整數(shù)。轉(zhuǎn)換出錯(cuò)的分界點(diǎn)是2147483584.0。
2.轉(zhuǎn)換成功的情況
小于16777215.0左右轉(zhuǎn)換結(jié)果完全正確。轉(zhuǎn)換成功時(shí)ov和os為0。
小于2147483584.0到16777215.0這一段可以轉(zhuǎn)換,但是轉(zhuǎn)換有誤差。
接近2147483584.0時(shí),最大誤差為64。
大于2147483456.0 ~ 2147483584.0時(shí)(區(qū)間范圍為128.0),轉(zhuǎn)換后得到的雙整數(shù)均為2147483520(16#7fff ff80,見下圖)。轉(zhuǎn)換結(jié)果2147483520是區(qū)間中點(diǎn)的值,(2147483456 + 2147483584)/2= 2147483520。
大于2147483328.0 ~ 2147483456.0時(shí),轉(zhuǎn)換后得到的雙整數(shù)均為2147483392(16#7fff ff00)。
大于2147483200.0 ~ 2147483328.0時(shí),轉(zhuǎn)換后得到的雙整數(shù)均為2147483264(16#7fff fe80)。
經(jīng)過分析,我已經(jīng)找到了上述現(xiàn)象的原因,結(jié)果暫不公布,希望有興趣的網(wǎng)友一起來分析一下,共享解決問題的快樂。
3.轉(zhuǎn)換結(jié)果分析
大于2147483456.0 ~ 2147483584.0時(shí)轉(zhuǎn)換后得到2147483520(16#7fff ff80)。
大于2147483328.0 ~ 2147483456.0時(shí)轉(zhuǎn)換后得到2147483392(16#7fff ff00)。
大于2147483200.0 ~ 2147483328.0時(shí)轉(zhuǎn)換后得到2147483264(16#7fff fe80)。
上述3個(gè)區(qū)間內(nèi)部的間隔為128.0,轉(zhuǎn)換結(jié)果為區(qū)間的中點(diǎn)(2147483456 + 2147483584)/2= 2147483520。
所以這種轉(zhuǎn)換并不精確,最大誤差為128/2=64。
浮點(diǎn)數(shù)轉(zhuǎn)換為雙整數(shù)的轉(zhuǎn)換誤差的根本原因是32位浮點(diǎn)數(shù)和32位雙整數(shù)的有效位數(shù)的差異造成的。
浮點(diǎn)數(shù)由一位符號(hào)位、8位指數(shù)和尾數(shù)的小數(shù)部分(23位)組成。尾數(shù)的位數(shù)決定了浮點(diǎn)數(shù)的精度。尾數(shù)的整數(shù)部分為1,小數(shù)部分為23位,所以尾數(shù)的有效數(shù)字為24位。
雙整數(shù)除去一位符號(hào)位,其有效位數(shù)為31位,因此浮點(diǎn)數(shù)的有效位數(shù)比雙整數(shù)少7位。
2147483456.0 ~ 2147483584.0相差128.0,它們對(duì)應(yīng)的整數(shù)為31位有效數(shù)字,這些浮點(diǎn)數(shù)輸入plc后,因?yàn)楦↑c(diǎn)數(shù)的有效位數(shù)只有24位,它們的尾數(shù)相同,對(duì)應(yīng)的十六進(jìn)制表示的浮點(diǎn)數(shù)均為16#4eff ffff,或2.17484e+009(注意有效尾數(shù)為十進(jìn)制7位,而不是對(duì)應(yīng)的整數(shù)的10位)。所以轉(zhuǎn)換為雙整數(shù)后均為2147483520。
ktissot網(wǎng)友說:“這就像看一片湖水一樣,你可以看到水和浪花,但是絕對(duì)看不到水分子。”由于有效位數(shù)較小,浮點(diǎn)數(shù)不能分辨“水分子”2147483457.0 ~ 2147483584.0,我們只能看到“浪花”2147483520(16#7fff ff80)。
如果浮點(diǎn)數(shù)較小,例如小于16777215(16#ff ffff),整數(shù)部分只有24位,轉(zhuǎn)換后就沒有上述的誤差了。在此基礎(chǔ)上增大,整數(shù)部分的位數(shù)越大,誤差越大。
因?yàn)橛行粩?shù)相差7位,在接近雙整數(shù)最大值的區(qū)段,浮點(diǎn)數(shù)的尾數(shù)相差一個(gè)數(shù)時(shí),轉(zhuǎn)換為雙整數(shù)后,相差128。2的7次方等于128。
4.高端轉(zhuǎn)換出錯(cuò)的原因分析
為什么最高端大于2147483584.0的數(shù)不能正確地轉(zhuǎn)換呢?請(qǐng)注意小于2147483648.0到大于2147483584.0這段范圍剛好是64.0(128.0的一半)。rnd指令在轉(zhuǎn)換時(shí)將這段范圍的尾數(shù)四舍五入后,尾數(shù)的最低位加1,相當(dāng)于轉(zhuǎn)換后的整數(shù)加128(16#80),由上述的16#7fff ff80(2147483520)加16#80后變?yōu)?6#8000 0000,超出了雙整數(shù)整數(shù)的允許范圍,產(chǎn)生了溢出,所以轉(zhuǎn)換出錯(cuò)。
上一個(gè):買域名的問題-域名及賬戶問題
下一個(gè):刑事逮捕以后家屬能夠見面嗎

進(jìn)程registry(進(jìn)程aissca.exe)
新東方培訓(xùn)收費(fèi)價(jià)格表,新東方英語培訓(xùn)收費(fèi)情況
茶里的十個(gè)暗語,不懂可是要吃虧!
R30-25F軟管連接玻璃轉(zhuǎn)子流量計(jì)圖片
主板h61和h81哪個(gè)好,H61和H81有什么區(qū)別
婚檢需要準(zhǔn)備什么資料?婚檢流程
刑滿釋放去哪領(lǐng)補(bǔ)助金
小米5s的sim卡怎么剪
中國(guó)茶葉發(fā)展歷龑史
三星電腦開機(jī)后黑屏進(jìn)入不了桌面
十八禁 网站在线观看免费视频_2020av天堂网_一 级 黄 色 片免费网站_绝顶高潮合集Videos