SAS數值變數的儲存與運算

0
SAS在處理數值性變數時,並不是用我們日常生活用的十進位運算,而是用64位元浮點表示法(64 bits floating-point repressions)來儲存數值性資料,有關64 bits floating-point repressions的詳細敘述可以參考(the IEEE_754 Standard, double precision),在整數部份,64位元浮點運算是沒有問題的,但在小數或者說是分數的運算上,則64位元浮點運算則會有誤差的產生,我們將舉一個例子來說明這種情況,並建議幾個方法來避免這些問題的產生.

範例:我們產生2個資料集(s和t)但是s和t的資料集中變數i產生的方式不同,之後我們根據變數i合併2個資料集(s和t)取名為p
data s;
do i =.1 to .9 by .1;
a=i;
output;
end;
data t;
do i =.1,.2,.3,.4,.5,.6,.7,.8,.9;
b=i;
output;
end;
data p;
merge s t;
by i;
proc print;
run;
由下面的output中,我們發現i在0.3,0.8,0.9的時候,SAS在合併s和t時,認定兩個資料集中的i變數不同,所以才會產生下面的結果。
21
可是p資料集的兩筆資料都是0.3,0.8,0.9,為什麼SAS會認為不一樣呢?我們可以執行下面的程式後可以看得更仔細
data s;
do i =.1 to .9 by .1;
a=i;
a1=put(i,hex16.);
output;
end;
data t;
do i =.1,.2,.3,.4,.5,.6,.7,.8,.9;
b=i;
b1=put(i,hex16.);
output;
end;
data p;
merge s t;
by i;
proc print;
var i a b a1 b1;
run;
由下表看得出觀測值第3,4筆的值雖都顯示為0.3.但是我們利用hex16格式顯示資料時,會發現兩者並非全然相等,而是有些微的差距,
22
SAS在呈現資料時是採取BEST.的方式,所以在Output的呈現因精確度的關係呈現的結果雖然是一樣,但是其實是有些微的差距.這是因為資料集s的0.3是0.1+0.1+0.1而來的,下表為對照的浮點運算儲存值
數值
浮點運算值
0.2+0.1
0011111111010011001100110011001100110011001100110011001100110100
0.3
0011111111010011001100110011001100110011001100110011001100110011
如何去避免這些問題,最主要是要去避免分數的運算(fraction operations)
  1. 盡量使用整數
data s;
do j = 1 to 9;
i=j/10;
output;
end;
  1. 如果使用小數時,盡量不要用累進的方式
data t;
do i =.1,.2,.3,.4,.5,.6,.7,.8,.9;
output;
end;
  1. 如果用累進的方式,可以使用round函數
data s;
do j =.1 to .9 by .1;
i=round(j,.1);
output;
end;
Tags
Share

About Author

SAS Taiwan

SAS 學習資源 : https://blogs.sas.com/content/sastaiwan/

Comments are closed.

Back to Top