導航:首頁 > 源碼編譯 > 浮點運算演算法

浮點運算演算法

發布時間:2023-01-14 01:42:53

㈠ 浮點運算 是什麼

浮點運算簡介

對於習慣於C的靈活多變的數據類型和方便的計算那些人而言,了解底層的浮點運算似乎沒有什麼意義,現在Visual盛行的時代還有多少人關心那些所謂的底層呢?
對了AfOs來說,浮點運算是編程中很重要的一部分,因為我們可能會面臨一些稍微復雜的運算,如果你和我一樣是Die-hard的asm擁護者,不想輕易用C來解決問題,你肯定能想像在asm下用整數運算求sin(2.3)的痛苦,實際上,微機早就為我們准備了解決之道:那就是浮點運算.但現在關於浮點運算的資料較少,相信很多人和我一樣還不掌握這種強有力的技術,那好,我們一起來學習學習.

(一)浮點數
(This Part mainly Froe Bill's Article)
在這之前,先來看幾個術語:
FPU->Floating Point Unit,浮點運算部件
BCD->Binary Coded Decimal 壓縮的二十進制數,是用4個位來表示數字0~9,一個byte表示兩個十進制數,比如01111001表示89
科學計數法:這是科學的~~~~具體含義查查初中還是小學的數學課本 D:)

浮點運算使用三種不同的數據:
1)整數(Integer),又分為字,短整數(Short Integer)和長整數(Long Integer)
2)實數(Real)分單精度(Single Real)和雙精度(Double Real)
3)壓縮的二十進制數(BCD)

下面是其位數(bits)和能表示的大致范圍和

Type Length Range
-----------------------------------------------
Word Integer 16 bit -32768 to 32768
Short Integer 32 bit -2.14e9 to 2.14e9
Long Integer 64 bit -9.22e18 to 9.22e18
Single Real 32 bit 1.18e-38 to 3.40e38
Double Real 64 bit 2.23e-308 to 1.79e308
extended Real 80 bit 3.37e-1932 to 1.18e4932
Packed BCD 80 bit -1e18 to 1e18

雙精度數和擴展精度數表示範圍對一般應用來說已經足夠大了!

1)整數,以補碼形式存儲,正數的補碼是其本身,負數補碼是其絕對值的各位變反後加1,下面是實際存儲的例子:
0024 var1 dw 24
FFFE var2 dw -2
000004D2 var3 dd 1234
FFFFFF85 var4 dd -123
0000000000002694var5 dq 9876
FFFFFFFFFFFFFEBFvar6 dq -321

2)BCD數
在FPU中用80位表示正好是浮點堆寄存器的寬度,在其格式如下存儲:
Bit
79___72_71________________________________________0
符號 ---18個二十進制數--------
看下面的例子:
00000000000000012345 var1 dt 12345
80000000000000000100 var2 dt -100

3)浮點數,這個復雜點,有三種格式

單精度:_31_30________23_22___________0
符號 指數 有效數

雙精度:_63_62__________52_51__________________0
符號 指數 有效數

擴展精度數:
_79_78____________64_63___________________0
符號 指數 有效數
例子:
C377999A var1 dd -247.6
40000000 var2 dd 2.0
486F4200 var3 real4 2.45e+5
4059100000000000 var4 dq 100.25
3F543BF727136A40 var5 real8 0.00123

C377999A var1 dd -247.6
40000000 var2 dd 2.0
486F4200 var3 real4 2.45e+5
4059100000000000 var4 dq 100.25
3F543BF727136A40 var5 real8 0.001235
400487F34D6A161E4F76 var6 real10 33.9876

DD和real4都可以在asm中來定義單精度浮點數,4 bytes
DQ和real8都可以在asm中來定義雙精度浮點數,8 bytes
DT和real10都可以在asm中來定義擴展精度浮點數,10 bytes

(二)浮點部件

FPU從功能上分為兩個部分:控制單元和運算單元,控制單元主要面向CPU,而算數單元負責具體算數運算.
FPU即浮點部件包括8個通用寄存器,5個錯誤指針寄存器和三個控制寄存器.

1)8個通用寄存器每個80 bit,形成一個寄存器堆棧,所有的計算結果都保存在寄存器堆棧中,其中數據全部是80位的擴展精度格式,即使是BCD,整數,單精度和雙精度等在裝入寄存器的時候都要被FPU自動轉化為80位的擴展精度格式,注意棧頂通常表示為ST(0),然後是ST(1)...ST(i),ST(i)是相對於棧頂而言的.

和堆棧很相似,只不過寬度為80bit,映像如下:
_______________________
| ST(0) |
|_______________________|
| ST(1) |
|_______________________|
| ...... |
| ...... |
| ST(i) |
|_______________________|

2)控制寄存器,FPU有三個控制寄存器:狀態寄存器,控制寄存器和標記寄存器

狀態寄存器->SW
_M_____D________10___9____8___7_________5_________________________0__
| B | C3| TOP| C2 | C1 | C0 | ES | | PE | UE | OE | ZE | DE | IE |
|____|____|____|____|____|____|____|____|____|____|____|____|____|____|

B: 浮點部件正忙
C0-C3 指示浮點運算的結果,不同指令有不同含義
TOP 指示棧頂,通常是0
ES 以下任何位置位 (pe, ue, oe, ze, de, or ie) 則置位
PE 精度故障
UE 數字太小無法表示溢出
OE 現有精度無法表示,數字太大溢出
ZE 除0錯
DE 指示至少有一個操作數未規格化
IE 無效錯誤,指示堆棧上溢或下溢,無效操作數等

控制寄存器:
_15____________10___9____8___7_________5______________________0__
| |IC | RC | PC | | PM | UM | OM | ZM | DM | IM |
|____|____|____|___|__|_|__|__|____|____|____|____|____|____|____|

IC 無窮大控制,對486,已經無效
RC 舍入控制
00 = 朝最接近或者偶數舍入
01 = 朝負無窮大方向舍入
10 = 朝正無窮大方向舍入
11 = 超0方向截斷
PC 精度控制
00 = 單精度
01 = 保留
10 = 雙精度
11 = 擴展精度
PM~IM 屏蔽狀態寄存器低5位指示的錯誤.為1則屏蔽.

標記寄存器:
每2 bit表示一個對應堆棧寄存器的狀態,具體含義如下:
15________________________________________3_____0
|Tag7 |...................................|tag1|
|_____|___________________________________|____|

含義:
00 = 有效
01 = 零
10 = 無效或無窮大
11 = 為空

(三)浮點指令系統及MASM下浮點程序設計

事實上最重要和比較難於找到資料在(一)和(二)部分中已經介紹,下面是為了完整性的考慮,如果你是第一次接觸浮點指令,看看下面的摘要也無妨.另外本文未涉及到的一個方面是關於浮點處理異常的情況,因為涉及到保護模式和中斷、任務切換以及SEH等較多內容,我相信介紹之後只會令人更加迷惑,況且我現在似乎也無法把這幾個問題完全說清除,一般我們幾乎不需要知道這些.讓我們先來看主要內容.

關於浮點程序設計是一個大的話題,我只是提綱挈領地簡述Masm32V7(/V6)中的設計方法,因為486以上的CPU內建了浮點部件所以可以在程序里直接使用浮點指令.下面是一個小例子:

__MASMSTD equ 1
.386p
.model flat, stdcall
option casemap :none ; case sensitive
include c:\hd\hd.h
include c:\hd\mac.h

;;--------------
.DATA
num1 dq 12345
num2 dq 98765
res dd 0
.DATA?
buf db 200 p(?)

;;-----------------------------------------
.CODE
__Start:
finit ;初始化浮點部件
fild num1 ;裝入num1
fild num2 ;裝入num2
fmul ;執行乘法
fist res ;存儲
invoke wsprintf,addr buf,CTEXT("the result is: %ld"),res
invoke StdOut,addr buf ;顯示,注意是控制台顯示,編譯用/SUBSYSTEM:CONSOLE

invoke StdIn,addr buf,20
invoke ExitProcess,0
END __Start

具體你要怎樣運用指令,那就得看你自己所要進行的操作和要執行的演算法了.注意在fpu內部寄存器總是以擴展精度數來表示數值的,因此進行整數運算最後要用fist來存儲,這樣才能得到正確的結果,這些轉換是由fpu自動完成的.

浮點指令系統分為五類:數據傳送類、算術運算類、超越函數類、比較類、環境及系統控制類.
我並不想列出所有函數的參數以及用法,因為這會是勞動力的浪費.我打字用拼音的!:D)具體參考資料見文章最後,別的我就幫不上你了.

1)數據傳送類,主要包括
這類指令主要是從內存裝入浮點寄存器堆數據,一般目的地址總是棧頂ST(0),用調試器你可以清除的看到這一點.注意帶P結尾的操作,是在前面操作完成之後出棧,也就是原來ST(1)的內容現在成了ST(0)的內容,注意到這一點,你可以方便地設計出靈活多變的程序.
裝入:
FLD Push real onto stack
FILD Convert two's complement integer to real and push
FBLD Convert BCD to real and push to stack
存儲:
FST Store floating-point number from stack
FSTP Convert top of stack to integer
FIST
FISTP Convert top of stack to integer
FBSTP Store BCD to integer and pop stack
交換:
FXCH Exchange top two stack elements
常數裝載:
FLD1 裝入常數1.0
FLDZ 裝入常數0.0
FLDPI 裝入常數pi (=3.1415926....精度足夠,放心使用)
FLDL2E 裝入常數log(2)e
FLDL2T 裝入常數log(2)10
FLDLG2 裝入常數log(10)2
FLDLN2 裝入常數Log(e)2

我逼並不想列出所有的浮點指令的詳細格式,因為沒有必要!很多資料都有這些指令格式的介紹,浮點指令均以F開頭,LD表示Load,ILD表示整數的Load,BLD是二十進制數的Load,這樣記起來就很容易了,很多指令功能都可以根據指令一眼看出來.

2)算術運算類
加法:
FADD/FADDP Add/add and pop
FIADD Integer add
減法:
FSUB/FSUBP Subtract/subtract and pop
FSUBR/FSUBRP Subtract/subtract and pop with reversed operands
FISUB Integer subtract
FISUBR Integer subtract/subtract with reversed operands
乘法:
FMUL/FMULP Multiply/multiply and pop
FIMUL Integer multiply
除法:
FDIV/FDIVP Divide/divide and pop
FIDIV Integer divide
FDIVR/FDIVRP Divide/divide and pop with reversed operands
FIDIVR integer divide with reversed operands
其他:
FABS Calculate absolute value
FCHS Change sign
FRNDINT Round to integer
FSQRT Calculate square root
FSCALE Scale top of stack by power of 2
FXTRACT Separate exponent and mantissa
FPREM Calculate partial remainder
FPREM1 Calculate partial remainder in IEEE format

如果指令後面未帶操作數,其默認的操作數為ST(0)和ST(1),關於帶R後綴的指令是正常操作數的順序變反,比如fsub執行的是x-y,fsubr執行的就是y-x.

3)超越函數類
三角函數
FSIN Calculate sine
FCOS Calculate cosine
FSINCOS Calculate quick sine and cosine
FPTAN Calculate partial tangent
FPATAN Calculate partial arctangent
Log類
FYL2X Calculate y times log base 2 of x
FYL2XP1 Calculate y times log base 2 of (x+1)
F2XM1 Calculate (2^x)-1

4)比較類
FCOM Compare
FCOMP Compare and pop
FICOM Integer compare
FTST Integer compare and pop
FUCOM Unordered compare
FUCOMP Unordered compare and pop
FXAM Set condition code bits for value at top of stack
FSTSW Store status word

會根據結果設置,C0~C3,在上面並未就C0~C3進行具體介紹,C1是用來判斷上溢或者下溢的,C0相當於EFLAGS裡面的CF,作用也基本一致,C2相當於PF,C3相當於ZF,你可能會看到如下指令
FSTSW ax
SAHF
JZ label
為什麼如此呢,因為用如上指令將狀態字存入EFLAGS,C0正好置於CF位,C3正好置於ZF位.

5)環境及系統控制類
FLDCW Load control word
FSTCW Store control word
FSTSW Store status word
FLDENV Load environment block
FSTENV Store environment block
FSAVE Save coprocessor state
FRSTOR Restore coprocessor state

FINIT Initialize coprocessor
FCLEX Clear exception flags
FINCSTP Increment stack pointer
FDECSTP Decrement stack pointer
FFREE Mark element as free
FNOP No operation
FWAIT Wait until floating-point instruction complete

我實在不想羅嗦了,因為這些指令的格式以及用法在Masm32V7的help目錄下面的fphelp.hlp文件中有詳細的說明,當然也還有很多其他的指令格式列表,我之所以列出來是為了完整性.這里還有一個比較困難的問題就是浮點數的顯示,windows沒有現成的函數調用,wsprintf只能顯示整數,但有好多庫支持,比如LYB主頁上的浮點開發包,當然等你搞熟了這些東西,也可以自己寫.

關於浮點程序的調試,建議使用Softice,因為Trw不支持浮點堆棧的顯示,現在網上有一個fpu插件,可以部分解決問題,不過不夠好用.一切看你自己的選擇

㈡ 浮點數的四種運算規則

浮點數實際上就是使用科學記數法來表示數字。

科學記數法就是將一個數字表示為一個1到10之間的小數×10的n次方,比如-3294728可以表示為-3.294728×10^6,這里^代表次方,也就是冪運算。

上面的字母僅僅是個示意,你隨便換成誰都可以,只要你自己懂了就行了~

接著說浮點數。計算機裡面浮點數就是四個部分:數符——小數的符號,就像我舉的例子裡面的-號;尾數就是3.294728;階符就是指數的符號,我舉的例子裡面因為是正6所以階符是+;階碼就是冪的數字6。精度決定了你這個數字能精確到多少位,如果精度低那就只有3×10^6,精度高一點3.295×10^6,等等。

關於編程方面的數學,其實和普通的數學差不多,這些底層的東西,如果你不是主業為編程,使用的又是高級一點的語言的話可以暫時不用理解這些東西,編程的時候演算法才是靈魂。

如果你主修的是計算機科學得話學校會開課的,如果是業余愛好得話就把高中初中老師教的東西學好就成了

㈢ 浮點數加法運算器

浮點數的基本運算包括加法、減法、乘法和除法。目前浮點加法演算法主要有基本演算法、Two-Path演算法和Triple-data-path演算法。在一般的處理器中,浮點加法、減法、轉換和傳送最終都是可以轉換為採用浮點加法器實現,所以浮點加法器的使用頻率高達55%,是使用頻率最高的浮點運算模塊。

第1步:比較數據大小,以便對數據小的尾數進行移位,從而在尾數運算前完成對階的工作。

第2步:對尾數進行加(減)法運算。

第3步:對運算結果格式化,還原為IEEE浮點格式。浮點加法器框圖如圖所示

單片機三位元組浮點數演算法

唉,給你出這個題目的人的腦子一定是壞掉了!

既然是用C語言,還用自己編程實現來浮點數演算法嗎?

閱讀全文

與浮點運算演算法相關的資料

熱點內容
vb編程10個隨機函數 瀏覽:19
程序員個人簡介100 瀏覽:770
土木工程師演算法工程師 瀏覽:90
javaexcel導入oracle 瀏覽:877
如何設置異地伺服器 瀏覽:882
為什麼安卓手機藍牙耳機不會彈窗 瀏覽:546
linuxf77編譯器安裝教程 瀏覽:949
android本地錄音許可權 瀏覽:446
加密u盤內容怎麼拷貝 瀏覽:283
安卓手機為什麼看不到iso文件 瀏覽:582
用圖片做文件夾圖標 瀏覽:693
java正則表達式語法 瀏覽:865
美圖秀在線壓縮圖片 瀏覽:184
蘋果自帶控制app是什麼 瀏覽:907
孩子學編程怎麼樣 瀏覽:589
網路編程經典書籍 瀏覽:612
曲靖創建網站java程序員 瀏覽:690
256位加密中是什麼意思 瀏覽:97
php多維數組去重 瀏覽:308
做程序員這一行儲備人才怎麼看 瀏覽:462