2011-03-10 58 views
5

使用$ HEX格式,很容易在SAS中基于基数16将数字转换为字母数字值。现在我正在寻找一个简单的方法来做到这一点与36基数(10个数字& 26个字母)。将数字转换为基于基数的字母数字值36

实例:

  • 100 - > '2S'
  • 2000 - > '1JK'
  • 30000 - > 'n5c'
  • 400000 - > '8kn4'

在Java中,您可以通过Integer.toString(mynumber, 36)来完成此操作。任何想法如何在SAS Base中执行此操作?

回答

3

不幸的是,有一种简单的方法可以使用格式来完成它,但下面的数据步骤应该可以解决这个问题。它仅适用于正整数。

data _null_; 
infile cards; 
input innumber; 
number = innumber; 
format base $32.; 
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
if number = 0 then base = '0'; 
else 
    do while (number ne 0); 
    mod = mod(number, length(alphabet)); 
    div = floor(number/(length(alphabet))); 
    base = cats(substr(alphabet,mod+1,1),base); 
    number = div; 
    end; 
put innumber= base=; 
cards; 
0 
100 
2000 
30000 
400000 
; 
run; 
+0

看起来不错!我已经知道Java中的算法,基数大于36,但我之前没有看到SAS实现。谢谢! – TechnoCore 2011-03-10 14:58:39

1

这里没有内置的功能。你可以迭代模36你的数字,然后除以36,直到剩下的为零。要转换modulos序列,你必须添加48decimal或30hex来获得ascii字符的情况下的数字0-9和101decimal或65hex获得ascii字符的情况下的数字A - Z。

1

我建议使用PROC FCMP创建自己的函数来完成格式化。那么你可以随时重复使用代码:

proc fcmp outlib=sasuser.funcs.Radix36; 
    function Radix36(innumber) $ 32; /* returns character string, length 32 */ 
    number = innumber; 
    format base $32.; 
    alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
    if number = 0 then base = '0'; 
    else do while (number ne 0); 
     mod = mod(number, length(alphabet)); 
     div = floor(number/(length(alphabet))); 
     base = cats(substr(alphabet,mod+1,1),base); 
     number = div; 
    end; 
    return (base); 
    endsub; 
run; 

/*****************************************************/ 
options cmplib=sasuser.funcs; /* add to search path */ 
data _null_; 
input innumber; 
base = Radix36(innumber); /* call function */ 
put innumber= base=; 
datalines; 
0 
100 
2000 
30000 
400000 
; 
run;