查看“︁定點數運算”︁的源代码
←
定點數運算
跳转到导航
跳转到搜索
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
{{Original research|time=2021-08-23T13:30:46+00:00}} {{noteTA|G1=IT}} 在電腦中,'''定点数'''({{lang-en|fixed-point number}})是指用固定整數位數表達[[分數]]的格式,屬於[[实数]][[数据类型]]中一種。例如[[美元]]常會表示到二位小數,以[[分 (货币单位)|分]]來表示,即為一種定点数。有時定点数也會要求要有固定的整數位數。定点数与更复杂的[[浮点数]]相对。 在定点数表示法中,小數部份和整數部份一樣,也會表示為進制[[底数 (进制)|底数]]''b''的幂次,不過是以負數幂次來表示。最常見的定点数表示法是[[十进制]](底数為10)和[[二进制]](底数為2)。若儲存了''n''位的小數,其數值一定是''b''<sup>−''n''</sup>的整數倍。定点数表示法也會用來省略整數中較低位數的值,例如將金錢表示為1000美元的整數倍。 在人們處理有小數的十进制數字時,會在整數和小數之間加上[[小數點]]('.'或是',')。不過定点数中,整數和小數的位數長度是依程式的規畫來決定。 在[[机械计算器]]中主要會使用定點數運算。由於大多數現代的[[中央处理器]]就有[[浮点运算器]](FPU),只有在特殊的應用中才使用定點數運算,例如低價的[[嵌入式系统]][[微处理器]]以及[[单片机]],這類的應用強調高需求速度,低電力需求及小[[集成电路]]區域,例如[[影像處理|影像]]、{{le|視頻處理|video processing|視頻}}或[[数字信号处理]],或是一些這種表示法比較適合問題本質的議題。後者的例子是[[会计学]]的金錢單位,非整數的金額也需要進行四捨五入,另一種情形是在產生[[函数]]的[[查找表]]。 == 表示法 == {| class="wikitable" style="margin:0 0 0 1em; text-align:right; float:right;" |+ 定點數表示法 |+ 係數1/100 |- ! 小數數值 !! 用整數表示的值 |- | 0.00|| 0 |- | 0.5|| 50 |- | 0.99|| 99 |- | 2|| 200 |- | −14.1|| −1410 |- | 314.160|| 31416 |} 定点数类型的值其实就是个[[整数]],需要额外做比例进位,进多少位需要根据具体的定点数类型决定。例如 1.23 使用 1/1000 缩放系数的定点数表示时是 1230;1,230,000 使用 1000 缩放系数的定点数表示也是 1230。与浮点数不同,相同类型的定点数中所有值的缩放系数都是一致的,在计算过程中也保持不变。此表示法可以用標準的整數[[算術邏輯單元]]來進行[[有理数]]的計算。 二進制定點數下的負數常常會用[[二補數]]型式下的有號整數表示,其中隱含著缩放係数(或小數長度)。數值的正負號會依最高位元而定(1表示負值,0表示正值)。就是小數位數等於或大於整個數字的位置也是如此。例如,8位元二進制有號整數(11110101)<sub>2</sub> = −11,若分別配合-3, +5及+12的隱含小數長度,數值為−11/2<sup>−3</sup> = −88、−11/2<sup>5</sup> = −0.34375、和−11/2<sup>12</sup> = −0.002685546875。 另一種作法,負號可以用「符號-大小」的[[有符號數處理]]表示法以整數來表示,另外表示正負號,也有隱含的缩放係数。此作法常用於十進制的定點數貞算中。例如有號的十進制五位數 (−00025)<sub>10</sub>,配合-3, +5, and +12的隱含十進制小數長度,數值為−25/10<sup>−3</sup> = −25000、−25/10<sup>5</sup> = −0.00025和−25/10<sup>12</sup> = −0.000000000025。 程式一般會假設所有儲存在變數中的定點數,或是[[指令集架構]]產生的定點數,都會有相同的缩放係数。程式設計者可以依需要的[[测量精度]]以及實際數值的範圍來選擇缩放係数。 變數或是公式的縮放係數不一定會直接在程式碼中出現。好皊[[软件工程]]實務會要求在[[软件文档]]中說明縮放係數,至少也要在[[源代码]]的[[注释 (计算机语言)|注释]]中說明。 定点数的最大值,可以通过将其内部所使用的整数的最大值乘以缩放系数求得,最小值同理。 ===缩放系数的選擇=== 為了效率考量,缩放系数(scaling factor)一般會是基數''b''(2 或是 10)的正[[冪|冪次]],或是負冪次,因此實際內部仍然可以用類似整數的方式處理。不過缩放系数也需依應用而定。因此許多的數字可能其數值其實是用二進制記錄,但為了使用方便人类读写,缩放系数仍選擇10的幂,10的幂的缩放系数也可以配合[[国际单位制]],因為選擇特定的縮放係數,可能相當於使用另外一個大小較適合的單位,例如使用[[厘米]]或[[微米]],而不是使用[[米 (单位)|米]]。 不过有时也会使用其它缩放系数,例如可以用 1/3600 缩放系数的定点数来表示以小时为单位的时间值,可以精确到秒。 就算針對定點數進行最仔細的四捨五入,缩放係数''S''的定點數,其誤差最大會到其整數數±0.5,因此誤差的實際數值範圍是±0.5 ''S''。若縮放係數越小,所得到結果越準確。 不過,縮放係數越小也表示相同長度下所能記錄的數值會比較小。定點數下可以儲存的最大數值會對應可儲存的最大整數,再乘以轉換係數,其最小值也類似。例如,下表列出在16位元有號二進制定點數下,不同小數位元''f''下的缩放係数''S'',可以表示的最大值和最小值''V''<sub>min</sub>和''V''<sub>max</sub>,以及其精度''δ'' = ''S''/2。 {| class= "wikitable" style="margin:0 0 0 1em; float:center;" |+ 16位元有號二進制定點數的參數 |- ! ''f'' !! ''S'' !! ''δ'' !! ''V''<sub>min</sub> !!''V''<sub>max</sub> |- | −3 || 1/2<sup>−3</sup> = 8 || 4 || −0.262144 || +0.262143 |- | 0 || 1/2<sup>0</sup> = 1 || 0.5 || −0.032768 || +0.032767 |- | 5 || 1/2<sup>5</sup> = 1/32 || < 0.016 || −1024.00000 || +1023.96875 |- | 14 || 1/2<sup>14</sup> = 1/16384 || < 0.000031 || −2.00000000000000 ||+1.99993896484375 |- | 15 || 1/2<sup>15</sup> = 1/32768 || < 0.000016 || −1.000000000000000 ||+0.999969482421875 |- | 16 || 1/2<sup>16</sup> = 1/65536 || < 0.000008 || −0.5000000000000000 ||+ 0.4999847412109375 |- | 20 || 1/2<sup>20</sup> = 1/1048576 || < 0.0000005 || −0.03125000000000000000 || +0.03124904632568359375 |} ===精確值=== 在二進制的定點數中,考慮二進制下的分數''a''/2<sup>''m''</sup>(例如1/16或17/32),若其縮放係數為1/2<sup>''n''</sup>,且''n'' ≥ ''m'',即可以精確的用二進制定點數表示。不過大部份的十進制小數(如0.1或0.123)在二進制下會是無窮[[循环小数]],因此無法用二進制表示其精確值。 十進制的情形也類似,考慮十進制下的分數''a''/10<sup>''m''</sup>(例如1/100或37/1000)若其縮放係數為1/10<sup>''n''</sup>,且''n'' ≥ ''m'',即可以精確的用十進制定點數表示。若分母是二的次幂的分數''a''/2<sup>''m''</sup>(如1/8 (0.125)或17/32 (0.53125),且''n'' ≥ ''m'',也可以精確的用十進制定點數表示。 若考慮[[有理数]] ''a''/''b'',其中''a''和''b''[[互質]],''b''為正數。若用二進制的定點數表示,只有在''b''是2的次幂下才能表示其精確值,若用十進制的定點數表示,只有在''b''的質因數沒有2和5以外的數字時,才能表示其精確值。 === Q格式 === 表示字长和二进制定点数中小数点位置的方法有很多种。下面的例子中,使用 ''f'' 表示小数部分位数、''m'' 表示整数部分位数、''s'' 表示符号位位数、''b'' 表示总位数,其中「位数」均为[[位元|比特]]位。 * '''Q'''''f'':称作「Q 格式」,Q15 表示 15 个小数位。这样的记法存在歧义,因为没有包含字长,但实际使用时一般可以根据目标处理器平台判断字长为 16 或者 32 位。<ref name="ti"/> * '''Q'''''m'''''.'''''f'':无歧义的 Q 格式,因为整个字是[[二補數|补码整数]],所以符号位长度可以根据其它信息推导而来。例如 Q1.30 表示该数有 1 个整数位、30 个小数位,是 32 位补码整数。<ref name="ti"/><ref>{{cite web|url=http://www.mathworks.com/help/toolbox/fixedpoint/ref/bp7g699.html#f6811|title=MathWorks Fixed-Point Toolbox Documentation Glossary|author=|date=|website=mathworks.com|accessdate=2019-03-06|archive-date=2011-03-16|archive-url=https://web.archive.org/web/20110316070605/http://www.mathworks.com/help/toolbox/fixedpoint/ref/bp7g699.html#f6811|dead-url=yes}}</ref> * '''fx'''''m'''''.'''''b'':「fx 格式」与上述 Q 格式类似,区别在于点号后是字长。例如 fx1.16 表示有 1 个整数位、15 个小数位的 16 位字。<ref name="vsi"/> * ''s''''':'''''m''''':'''''f'':[[PS2]] 中所使用的表示法,包含符号位信息。<ref>PS2 GS User's Guide, Chapter 7.1 "Explanatory Notes"</ref>0:8:0 表示 8 位无符号整数。 ==和浮點數的比較== 定點數的運算比浮點數要快,需要的硬體也比較少。假如要計算的數值範圍事先就已知道,而且限制在較小的範圍內,定點數運算可以有效的使用其位元。例如,用32位元表示從0到1的數字,定點數下的誤差會小於1.2 × 10<sup>−10</sup>,而浮點數的誤差則為596 × 10<sup>−10</sup>,因為其中有九個位元表示指數以及指數的正負號,因此誤差較大。 使用定點數運算的程式,不會受到是否有[[浮點運算器]](FPU)的影響,可移植性比浮點數要高。在[[IEEE 754]]普及之前,相同資料在浮點運算後的結果會依處理器廠商而不同,因此此一優點影響很大。 許多早期的嵌入型系統沒有浮點運算器,整數運算單元需要的[[邏輯閘]]和[[集成电路]]較少,而且低速備下,用軟體模擬浮點運算的速度太慢,無法實用。早期[[个人电脑]]和[[電子遊戲機]]的處理器(例如[[Intel 80386]]和[[Intel 80486]])都沒有浮點運算器。 定點格式下的絕對解析度(二個連續數值之間的差),在整個數值範圍下都是定值,例如是缩放系数''S''。相反的定點格式下的相對解析度,在整個數值範圍下都是定值,但其絕對解析度會隨數值而變化,變化甚至會到數個數量值。 在許多應用中,定點運算的四捨五入以及捨去誤差比較好分析。不過在定点運算下,程式設計者需要花較多的心力,例如為了避免溢位,需要確認計算中所有中間值的範圍,為了要調整到理想的缩放系数,需要有額外的程式處理信號轉換。 ==應用== 十進制定點數常用在儲存貨幣價值上,因為浮點數的複雜捨入原則,往往會造成負擔。例如開源的現金管理應用程式,[[GnuCash]],以C語言撰寫,就因為此原因從1.6版起由浮點數改為定點數。 自從1960年代末期,一直到1980年代,二進制定點數常用在要用到大量數學實時計算的程式,例如[[飛行模擬器]]以及[[核电厂]]控制演算法。在許多[[数字信号处理]]應用或是客製的微處理器中仍常使用定點數。像有關角度的計算,就會使用{{le|二進制角度測量|binary angular measurement}}(BAM)。 在[[STM32|STM32G4]]系列的[[CORDIC]]協同處理器,以及[[JPEG]]影像壓縮使用的[[离散余弦变换]](DCT)演算法,都使用二進制定點數。 ==運算== ===加法和減法=== 若要針對二個縮放係數相同的數字相加或相減,直接針對數字運算即可,運算結果也會有相同的縮放係數,因此可以儲存在[[变量 (程序设计)|變數]]中,或是用在後續的運算中。只要運算過程沒有[[算術溢位]](也就是運算過程和結果都可以正確的儲存),其結果就會是精確的。若二個縮放係數不相同的數字要相加減,需轉換到相同的縮放係數,才能相加減。 ===乘法=== 若要將二個定點數相乘,可以直接將其數字相乘,再假設最後積的縮放係數是被乘數和乘數縮放係數的乘積即可。只要沒有捨入,也沒有運算溢位,結果會是精確的。 例如,要將123(缩放系数1/1000,實際數值是0.123)和25(缩放系数1/10,實際數值是2.5)會得到123×25 = 3075,缩放系数是(1/1000)×(1/10) = 1/10000,因此實際數值是0.3075。另一個例子是將第一個數字和155(缩放系数1/32,實際數值是155/32 = 4.84375)相乘,所得的數字是123×155 = 19065,其缩放系数是(1/1000)×(1/32) = 1/32000,因此實際數值是19065/32000 = 0.59578125。 為了避免溢位,儲存乘積的變數長度會比被乘數和乘數的要長,例如被乘數和乘數分別是十進制的二位數,乘積需要用十進制的四位數來儲存,才不會溢位。 ===除法=== 若要將二個定點數相除,可以直接將其數字相除,再假設最後商的縮放係數是被除數和除數縮放係數相除後的商即可。一般來說,相除時會出現捨入,因此結果無法完全精確。 例如,3456(缩放系数1/100,實際數值34.56)和1234(缩放系数1/1000,實際數值1.234)相除會得到3456÷1234 = 3(有捨入),其缩放系数為(1/100)/(1/1000) = 10,因此實際數值是30。若第一個數除以155(缩放系数1/32,實際數值155/32 = 4.84375),會得到3456÷155 = 22(有捨入),其缩放系数為(1/100)/(1/32) = 32/100 = 8/25,因此數值為22×32/100 = 7.04。 在結果不精確時,若被除數使用較小的缩放系数,可以縮小(甚至消除)因為捨入產生的誤差。例如,''r'' = 1.23,表示為定點數123,缩放系数1/100,而''s'' = 6.25,表示為6250,缩放系数1/1000,相除後的結果是123÷6250 = 0(有捨入),其缩放系数為(1/100)/(1/1000) = 10。若''r''先轉換為缩放系数1/1000000的數字,定點數表示會是1/1000000,其結果會是1,230,000÷625 = 197(有捨入),其缩放系数為1/1000(實際數值是0.197)。其精確值是1.23/6.25 = 0.1968,後者的計算結果比較接近。 ===缩放系数的調整=== 在定點數運算中,常常需要調整定點數的缩放系数,以下是一些可能的原因: * 將一數值存到不同缩放系数的變數中。 * 將二個數值轉換為相同的缩放系数,以便相加減或是比較。 * 一個數值在和其他數值相乘或是相除後,恢復成原來的缩放系数。 * 要增加除法運算的精度 * 要確保乘積或是商的缩放系数是像10<sup>''n''</sup>或2<sup>''n''</sup>,基數的次幂。 * 要確保運算結果可以在沒有溢位的情形下儲存在變數內。 * 為了要減少處理定點數硬體的成本。 若要將縮放係數''R''的定點數轉換為縮放係數''S''的定點數,整數需要乘以''R''/''S''。以1.23(= 123/100)為例,若要從縮放係數''R''=1/100,轉換為縮放係數''S''=1/1000,整數123要乘以(1/100)/(1/1000) = 10,因此即為1230/1000。 若二個縮放係數都是基數的次幂,調整縮放係數只是除去較低位數的數字,或是在較低位數增加零。不過,此一運算不能改變符號位元,因此需要像[[算术移位]]運算一樣的方式,延伸其符號位元。 若''R''不能被''S''整除(特別是新的縮放係數''S''比原來的縮放係數''R''要大),產生的整數需要進行[[数值修约]]。 若''r''和''s''是定點數,其縮放係數分別為''R''和''S'',運算''r'' ← ''r''×''s''需要將整數相乘,再除以''S'',所得結果可能會有数值修约,也有可能會溢位。 例如,二個定點數的縮放係數都是1/100,將1.23乘以0.25,其整數相乘是123乘以25,得到3075,而縮放係數是1/10000,為了還原到1/100的縮放係數,3075需乘以1/100,也就是除以100,依[[数值修约]]方法的不同,所得結果可能是31(0.31)或是30(0.30)。 而運算''r'' ← ''r''/''s''需要將整數相除,再乘以''S'',所得結果可能會有数值修约,也有可能會溢位。 ===和浮點數的轉換=== 若要將浮點數轉換為定點數,可以將浮點數除以縮放係數''S'',再修约到最接近的整數。需確認對應的變數有足夠的大小儲存所得的結果。依縮放係數、變數長度,以及數值大小的不同,轉換有可能需要修约。 若要將定點數轉換為浮點數,可以將定點數乘以縮放係數''S''。若整數的絕對值超過2<sup>24</sup>(IEEE單精度浮點數)或2<sup>53</sup>(IEEE雙精度浮點數),可能會需要修约。若|''S''|非常大或是非常小,可能會有溢位或[[算术下溢]](小於可以表示的最小數)的情形。 ==硬體支援== ===比例和正規化=== 一般的處理器沒有特別支援定點數的運算,不過大部份二進位運算的處理器會有快速的[[位操作]]指令,因此可以在很短的時間進行和二的乘幂的乘法或除法,有些還有[[算术移位]]指令,在和二的乘幂相乘除的同時,還可以保留數字的正負號。 早期像是{{le|IBM 1620|IBM 1620}}或是Burroughs B3500的電腦會使用[[二進碼十進數]](BCD)表示法來處理整數,在十進制下每一個位數會分別用四個次元來儲存,有些處理器還使用此一運算方式,因此可以用移位的方式來處理和十的乘幂相乘除的運算。 有些DSP架構會支援特定的定點運算格式,例如有號的''n''位元數字,其中有''n''−1位是儲存小數(其儲存數值範圍從-1到幾乎是+1的),其中會有特別包括正規化的乘法指令,在相乘後將小數位數從2''n''−2位調整回''n''−1位。若DSP沒有支援此一機能,程式設計者需要用夠大的暫存器或是暫存變數來儲存此數值,再另外用程式進行正規化處理。 ===溢位=== 若運算結果的數值太大,超過要儲存位置可以儲存的範圍,就會出現溢位。若是加法或是減法,所得結果會比運算數字多一個位元,若是乘法,所得結果的位元數會是二個運算數字位元數的和。 若出現溢位,最高位元的資訊可能會因此而更改,若儲存空間有''n''位元,所儲存的會是除以2<sup>''n''</sup>的餘數,而最高位元會視為符號位元,因此結果的大小及正負號都可能改變。 有些處理器有{{le|溢位旗標|overflow flag}},或是在溢位時進行的[[异常处理]]。有些處理器則會有[[饱和运算]],若相加或是相減的結果可能會溢位,考慮其正負號,儲存相同符號,絕對值最大的數值。, 饱和运算只保留了正負號,無法保留結果的大小,在實務上可能不太實用。一般比較簡單及安全的作法是選擇適當的缩放系数以及變數儲存長度,避免溢位的可能性,或者在運算之前先檢查運算結果是否可能溢位。 ==程式語言支援== 有些程式語言明確支援定點數表示法及運算,著名的有[[PL/I]]、[[COBOL]]、[[Ada]]、[[JOVIAL语言|JOVIAL]]及{{le|Coral 66|Coral 66}}。這些程式語言中提供定點數的數值[[資料類型]],可能是二進制或十進制,可以指定給變數或是函式。編譯器會在處理有關的程式碼時自動進行轉換,例如處理類似''r'' ← ''s'' × ''t'' + ''u''的程式碼,讀寫這些變數的值,或是將這些資料類型轉換為浮點數時。 這類的程式語言多半是在1940年至1990年之間設計的,現今的程式語言多半都不提供定點數資料類型,也不提供相關的係數轉換。有些較古老,但仍很受歡迎的程式語言也是如此,例如[[Fortran]]、[[C语言]]和[[C++]]。浮點處理器的普及,以及嚴格標準化的行為,大幅的減少二進制定點數的需求。有些程式語言支援{{le|十進制浮點數|decimal floating point}}(例如[[C♯]]和[[Python]]),也去除了大多數需要十進制固點數的需求。很少數需要固點數的情形,會由程式設計師寫程式實現,並且有明確的係數轉換,這在任何程式語言都可以實現。 另一方面,所有[[關聯式資料庫]]以及[[SQL]]表示法都支援用十進制定點數來進行數值的儲存以及運算。[[PostgreSQL]]有一種特別的<samp>numeric</samp>型態,可以精確的儲存數值,位數最多可以到1000位<ref>PostgreSQL manual, [http://www.postgresql.org/docs/8.3/static/datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL section 8.1.2. Arbitrary Precision Numbers] {{Wayback|url=http://www.postgresql.org/docs/8.3/static/datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL |date=20180309053053 }}</ref>。 [[國際標準化組織|ISO]]在2008年針對C語言提出了有關定點數資料型態的擴充提案,目的為了方便程式在嵌入式處理器上執行<ref>JTC1/SC22/WG14 (2008), [http://www.open-std.org/JTC1/SC22/WG14/www/projects#18037 status of TR 18037: Embedded C] {{Wayback|url=http://www.open-std.org/JTC1/SC22/WG14/www/projects#18037 |date=20220524205606 }}</ref>。[[GCC]]的[[編譯器]]也支援定點數<ref name=gccback/><ref name=gccuse/>。 == 具體範例 == ===十進制定點數乘法=== 以下是二個三位小數的定點數乘法。 (10.500)(1.050) =1*10.500 + 0.050*10.500 = 10.500+0.525000=11.025000 因為有三位小數,因此保留小數最後的0。為了要重整為整數乘法,先將數字都乘以1000,使數字都變成整數,之後再乘以<math>1/1000</math>二次,使最終結果不會改變,其算式如下 <pre> (10.500)(10^(3)) (1.050)(10^(3)) (10^(-3))(10^(-3)) = (10500)(1050) (10^-6) = 11 025 000 (10^-6) = 11.025000 </pre> 若用其他的進制(例如方便計算的二進制),也可以用類似的原理來進行,因為二進制的左移或右移都相當是數值的乘2或是除2。十進制的三位數接近二進制的十位數,因此可以將0.5表示為有十位小數的二進制數字。最低的近似值是0.0000110011. <pre> 10= 8+2=2^3+2^1 1=2^0 0.5= 2^-1 0.05= 0.0000110011(二進制) </pre> 乘法會變成 <pre> (1010.100)(2^3)(1.0000110011)(2^10) (2^-13) =(1010100)(10000110011) (2^-13) =(10110000010111100) (2^-13) =1011.0000010111100 </pre> 若轉為十進制,保留三位小數,會是11.023。 ===二進制定點數運算=== 考慮計算1.2乘5.6的乘積,使用有16位小數的二進制定點數。為了要表示這二個數字,需先將二個數字乘以2<sup>16</sup>,所得的是78643.2和367001.6,再四捨五入到最近整數,是78643和367002,此數字可以放在32位元的word中,用二補數的有號數表示法。 二個數字相乘會得到35位元的整數28862138286,小數位數則有32位。若放在32位元的整數中,會出現溢位,而且會失去最高位的位元,因此,應該存在有號的64位元整數變數或是[[寄存器]]中。 若結果要儲存在也是16位小數的資料格式中,上述的整數需要除以2<sup>16</sup>,結果會是440401.28,再四捨五入到最近整數,可以用先加上2<sup>15</sup>,再將數字右移16位元的方式達到相同效果,其結果是440401,表示的數值是6.7199859619140625。考慮此格式的精度,結果可以表示為6.719986 ± 0.000008(不考慮運算近似產生的誤差)。正確結果是1.2 × 5.6 = 6.72。 ==標示方式== 為了要精確的說明定點數的參數,有許多不同的標示方式。在以下的表中,''f''表示小數位元數,''m''表示整數位元數,''s''表示符號位元,而''b''是總位元數。 * [[COBOL]]程式語言一開始支援任意大小以及小數位數的十進制定點數,其格式會用<code>PIC</code>命令功能(directive)來標示。例如<code>PIC S9999V99</code>代表六位數整數,二位小數的的十進制有號數<ref name=cobibm/>。 * PL/I程式語言使用<code>REAL FIXED BINARY (</code>''p''<code>,</code>''f''<code>)</code>的construct來標示,標示二進制定點數,其中共有''p''位數(不考慮符號),其中小數是''f''位數,總共的有號整數有''p''+1位數,其轉換係數是1/2<sup>''f''</sup>。也可以用<code>COMPLEX</code> 代替<code>REAL</code>,用<code>DECIMAL</code>代替<code>BINARY</code>來表示十進制。 * 在[[Ada]]程式語言中,數值型態的表示法會像<code>type F is delta 0.01 range -100.0 .. 100.0</code>,表示用二補數格式的有號二進制表示法,其中小數位數是7位元(缩放系数是1/128),至少要用15位元來儲存(確保實際範圍可以從-128.00到將近+128.00)<ref name=adafix/>。 * [[Q格式]]是由[[德州仪器]]定義的<ref name="ti"/>。用<code>Q</code>''f''來表示有''f''位小數的有號定點數,例如<code>Q15</code>是缩放系数為1/2<sup>15</sup>的二補數有號數。而 <code>Q</code>''m''<code>.</code>''f''額外的標示數字的整數部份有''m''位(不算符號位元)。因此<code>Q1.30</code>表示有一位整數,30位小數的二進制定點數,可以存在32位元二補數整數中,缩放系数是1/2<sup>30</sup><ref name="ti"/><ref name=mwork/>。[[ARM架構]]也有類似的標示法,但其中的''m''有包括符號位元,因此上述的格式要改為<code>Q2.30</code><ref name="ARM_2001"/><ref name="ARM_2006"/>。 * {{le|VisSim|VisSim}}公司用<code>fx</code>''m''<code>.</code>''b''來表示共有''b''位元,小數有''m''位元的二進制定點數,因此是''b''位元的整數,缩放系数是1/2<sup>''b''−''m''</sup>。因此<code>fx1.16</code>是十六位元數字,整數部份1位元,小數部份15位元<ref name="vsi"/>。 * [[PlayStation 2]] GS(Graphics Synthesizer)使用者指南中用''s''<code>:</code>''m''<code>:</code>''f''的標示方式,其中''s''表示是否有符號位元<ref name=PS2/>。例如,<code>0:5:3</code>表示8位元整數,缩放系数是1/2<sup>3</sup>的無號數。 * [[LabVIEW]]程式語言的標示方式是<code><</code>''s''<code>,</code>''b''<code>,</code>''m''<code>></code>,表示FXP定點數的格式。''s''可以是'+'或'±',表示無號數或是二補數的有號數。''b''是總位元個數,而''m''是整數部份的位數。 ==軟體應用例== * 常用的[[TrueType]]字型格式,在一些指令中,使用32位元的有號二進制定點數,來表達數值<!--uses 32-bit signed binary fixed-point with 26 bits to the left of the decimal for some numeric values in its instructions.--><ref>{{Cite web|title = The TrueType Instruction Set: Data types|url = https://docs.microsoft.com/en-us/typography/opentype/otspec140/tt_instructions#dt|access-date = 2021-10-05|archive-date = 2022-05-06|archive-url = https://web.archive.org/web/20220506111628/https://docs.microsoft.com/en-us/typography/opentype/otspec140/tt_instructions#dt}}</ref>。這個格式是在考慮[[字体微调]]以及效能下,可以提供最小精度的格式<ref>{{Cite web|title = [Freetype] Why 26.6 ?|url = https://lists.nongnu.org/archive/html/freetype/2002-09/msg00076.html|access-date = 2021-10-05|archive-date = 2021-10-05|archive-url = https://web.archive.org/web/20211005154717/https://lists.nongnu.org/archive/html/freetype/2002-09/msg00076.html}}</ref>。 * Sony原生[[PlayStation]]和[[世嘉土星]]的所有3D計算引擎、任天堂的Game Boy Advance(其中的二维计算机图形)、[[任天堂DS]](2D和3D)、[[任天堂GameCube]]<ref>{{cite web|url=http://dolphin-emu.org/blog/2014/03/15/pixel-processing-problems/|title=Dolphin Emulator|website=Dolphin Emulator|access-date=2021-10-05|archive-date=2022-06-05|archive-url=https://web.archive.org/web/20220605223028/https://dolphin-emu.org/blog/2014/03/15/pixel-processing-problems/}}</ref>及GP2X Wiz電子遊戲系統,這些系統沒有浮點運算器,都使用定點運算。PlayStation中的轉換協處理器中有硬體支援16位元的浮點運算,其中有12位的小數。 * 廣為科學界和數學界使用的[[TeX]]軟體,在所有位置的運算中,使用32位元有號二進制定點數運算,其小數位數是16位。這個值的單位長度對應印刷中的[[點 (印刷)|點]]。TeX font metric檔案使用32位元定點數,其中有12位小數。 * {{le|Tremor (軟體)|Tremor (software)|Tremor}}、{{le|Toast (GSM)|Toast (GSM)|Toast}}和{{le|MPEG聲音解碼器|MPEG Audio Decoder}}都是軟體的函式庫,可以針對[[Vorbis]]、{{le|Full Rate|Full Rate|GSM Full Rate}}和[[MP3]]的聲音檔。這些解碼都使用定點運算,因為許多解碼硬體中沒有浮點運算器。 * [[WavPack]]無損聲音壓縮器也是使用定點運算。此決定有一部份是擔心不同硬體中對於浮點數的捨入規則差異會破壞壓縮器的無損特性<ref>{{Cite web|title = WavPack Technical Description|url = http://www.wavpack.com/technical.htm|website = www.wavpack.com|access-date = 2015-07-13|archive-date = 2021-02-25|archive-url = https://web.archive.org/web/20210225154201/https://www.wavpack.com/technical.htm}}</ref>。 * Nest Labs Utilities library<ref>{{Cite web |url=https://github.com/nestlabs/nlutilities |title=Nest Labs Utilities library |access-date=2021-10-05 |archive-date=2021-10-05 |archive-url=https://web.archive.org/web/20211005224915/https://github.com/nestlabs/nlutilities }}</ref>提供少量針對定點數的巨集以及函數,特別是用在處理和感測器取樣以及感測器輸出有關的數字。 * [[OpenGL ES]] 1.x規格中包括定點數,因為這是針對嵌入式系統的API,不一定有浮點運算器。 * [[Dc (程序)|Dc]]和[[Bc (编程语言)|Bc]]程式都是[[高精度计算]]計算器,但只支擾(使用者定義的)定點小數。 * {{le|Fractint|Fractint}}表達數字的方式類似[[Q格式]]的定點數<ref>{{Cite web |url=http://spanky.triumf.ca/www/fractint/periodicity.html#integer_math_anchor |title=Fractint, A Little Code |access-date=2021-10-05 |archive-date=2010-10-27 |archive-url=https://web.archive.org/web/20101027194454/http://spanky.triumf.ca/www/fractint/periodicity.html#integer_math_anchor }}</ref>,可以加速在[[Intel 80386]]或Intel 80486SX等沒有浮點運算器的舊電腦。 * [[毀滅戰士 (1993年遊戲)|毀滅戰士]]是[[Id Software]]所出的[[第一人称射击游戏]],其非整數運算(例如地圖系統、地理、算繪、玩家移動等)都是用16.16的定點格式。為了相容性考量,此表達法仍用在現代的Doom source port中。 * 有時在儲存或處理影像或是圖像幀時,會使用定點數。有[[单指令流多数据流]]單元,主要針對影像處理的處理器,一般都有適用於定點數的指令。 * [[Microsoft Azure]][[量子计算机]]的[[Q Sharp]]程式語言,是實現[[量子閘]]用的語言,其中包括標準的數值函數庫,可以在[[量子位元]]暫存器上處理定點運算<ref>{{Cite web|title = Introduction to the Quantum Numerics Library|url = https://docs.microsoft.com/en-us/quantum/libraries/numerics/?view=qsharp-preview|access-date = 2019-11-13}}</ref>。 == 相關條目 == * [[Q格式]] * [[浮点数]] * [[计算机编码]] * [[误差]]、[[数值修约]] * {{le|Libfixmath|Libfixmath}}:C語言的定點數函式庫 * {{le|對數數字系統|Logarithmic number system}} * [[迷你浮點數]] * {{le|塊浮點|Block floating-point scaling}} * [[模除]] * {{le|μ-law演算法|μ-law algorithm}} * {{le|A-law演算法|A-law algorithm}} == 参考文献 == {{reflist|refs= <ref name="ARM_2001">{{cite web |title=ARM Developer Suite AXD and armsd Debuggers Guide |version=1.2 |publisher=ARM Limited |at=Chapter 4.7.9. AXD > AXD Facilities > Data formatting > Q-format |date=2001 |orig-year=1999 |id=ARM DUI 0066D |url=http://infocenter.arm.com/help/topic/com.arm.doc.dui0066d/CHDFAAEI.html?resultof=%22%51%2d%66%6f%72%6d%61%74%22%20%22%71%2d%66%6f%72%6d%61%74%22%20 |url-status=live |archive-url=https://archive.today/20171104110547/http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0066d/CHDFAAEI.html |archive-date=2017-11-04 }}</ref> <ref name="ARM_2006">{{cite book |title=RealView Development Suite AXD and armsd Debuggers Guide |version=3.0 |publisher=ARM Limited |chapter=Chapter 4.7.9. AXD > AXD Facilities > Data formatting > Q-format |date=2006 |orig-year=1999 |id=ARM DUI 0066G |pages=4–24 |url=http://infocenter.arm.com/help/topic/com.arm.doc.dui0066g/DUI0066.pdf |url-status=live |archive-url=https://web.archive.org/web/20171104105632/http://infocenter.arm.com/help/topic/com.arm.doc.dui0066g/DUI0066.pdf |archive-date=2017-11-04}}</ref> <ref name="ti">Texas Instruments, [http://focus.ti.com/lit/ug/spru565b/spru565b.pdf TMS320C64x DSP Library Programmer's Reference] {{Wayback|url=http://focus.ti.com/lit/ug/spru565b/spru565b.pdf |date=20110604195035 }}, Appendix A.2</ref> <ref name=mwork>{{cite web|url=http://www.mathworks.com/help/toolbox/fixedpoint/ref/bp7g699.html#f6811|title=MathWorks Fixed-Point Toolbox Documentation Glossary|website=mathworks.com|access-date=2019-03-06|archive-date=2011-03-16|archive-url=https://web.archive.org/web/20110316070605/http://www.mathworks.com/help/toolbox/fixedpoint/ref/bp7g699.html#f6811|dead-url=yes}}</ref> <!-- <ref name=julia>Julia programming language documentation [https://github.com/JuliaMath/FixedPointNumbers.jl FixedPointNumbers package].</ref> --> <ref name=cobibm>IBM Corporation, "[https://www.ibm.com/docs/en/i/7.2?topic=rules-numeric-items#dcaprnu Numeric items] {{Wayback|url=https://www.ibm.com/docs/en/i/7.2?topic=rules-numeric-items#dcaprnu |date=20230208073653 }}". Online documentation site, accessedon 2021-07-05.</ref> <ref name=adafix>Ada 83 documentation: "[http://archive.adaic.com/standards/83rat/html/ratl-05-03.html#5.3.2 Rationale, 5.3.2: Fixed Point Types] {{Wayback|url=http://archive.adaic.com/standards/83rat/html/ratl-05-03.html#5.3.2 |date=20220809111918 }}". Accessed on 2021-07-05.</ref> <ref name="vsi">{{cite web|url=http://www.vissim.com/products/addons/vissim/fixed-point.html|title=VisSim is now solidThinking Embed|first=solidThinking|last=Inc.|website=www.vissim.com|access-date=2019-03-06|archive-date=2016-12-02|archive-url=https://web.archive.org/web/20161202171148/http://www.vissim.com/products/addons/vissim/fixed-point.html|dead-url=no}}</ref> <ref name=PS2>PS2 GS User's Guide, Chapter 7.1 "Explanatory Notes"</ref> <ref name=gccback>GCC wiki, [https://gcc.gnu.org/wiki/FixedPointArithmetic Fixed-Point Arithmetic Support] {{Wayback|url=https://gcc.gnu.org/wiki/FixedPointArithmetic |date=20230208073706 }}</ref> <ref name=gccuse>Using GCC, [https://gcc.gnu.org/onlinedocs/gcc/Fixed-Point.html section 5.13 Fixed-Point Types] {{Wayback|url=https://gcc.gnu.org/onlinedocs/gcc/Fixed-Point.html |date=20150529031814 }}</ref> }} {{数据类型}} [[Category:計算機算術]] [[Category:数据类型]]
该页面使用的模板:
Template:Cite web
(
查看源代码
)
Template:Lang-en
(
查看源代码
)
Template:Le
(
查看源代码
)
Template:NoteTA
(
查看源代码
)
Template:Original research
(
查看源代码
)
Template:Reflist
(
查看源代码
)
Template:Wayback
(
查看源代码
)
Template:数据类型
(
查看源代码
)
返回
定點數運算
。
导航菜单
个人工具
登录
命名空间
页面
讨论
不转换
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
工具
链入页面
相关更改
页面信息