【问题标题】:conversion from character to numeric when the length is 25长度为 25 时从字符转换为数字
【发布时间】:2014-08-22 09:29:42
【问题描述】:

我有一个字符格式的变量。例如,变量有一个值:112002500501002106302001,长度为 25。我想将其转换为数值变量。

我使用的是标准代码:

data trial1 ;
    set trial;
    code1 = input(CODE,25);
    run;

该值现在的格式为 1.120025E23

data trial1 ;
set trial;
code1 = input(CODE,25);
format code1 best25.;
run;

但我得到的结果并不准确。

我正在使用 sas 9.3

【问题讨论】:

    标签: formatting sas


    【解决方案1】:

    SAS 中的所有数字都是双精度数。来自维基百科 (http://en.wikipedia.org/wiki/Double-precision_floating-point_format) “在 2^52=4,503,599,627,370,496 和 2^53=9,007,199,254,740,992 之间,可表示的数字就是整数。”

    让我们运行一个循环将字符串转换为数字:

    data test;
    format x $25. y z best32.;
    x = '112002500501002106302001';
    a = '9,007,199,254,740,992';
    y = input(x,best32.);
    put x=;
    put y=;
    
    z = 0;
    do i=1 to 24;
        z = sum(z,10**(i-1)*input(substr(x,length(x)-i+1,1),best.));
        put i z= comma32.;
    end;
    run;
    

    输出:

    x=112002500501002106302001
    y=112002500501002105389056
    1 z=1
    2 z=1
    3 z=1
    4 z=2,001
    5 z=2,001
    6 z=302,001
    7 z=6,302,001
    8 z=6,302,001
    9 z=106,302,001
    10 z=2,106,302,001
    11 z=2,106,302,001
    12 z=2,106,302,001
    13 z=1,002,106,302,001
    14 z=1,002,106,302,001
    15 z=501,002,106,302,001
    16 z=501,002,106,302,001
    17 z=501,002,106,302,001
    18 z=500,501,002,106,302,016
    19 z=2,500,501,002,106,301,952
    20 z=2,500,501,002,106,301,952
    21 z=2,500,501,002,106,301,952
    22 z=2,002,500,501,002,106,175,488
    23 z=12,002,500,501,002,105,389,056
    24 z=112,002,500,501,002,088,611,840
    

    您会注意到在 17 和 18 次迭代之间,数字会分解。这超过了双精度不能再表示精确整数 (9,007,199,254,740,992) 的阈值。

    【讨论】:

      【解决方案2】:

      SAS 使用 8 个字节来存储数值变量。可以准确表示的整数的大小是有限制的。查看数值精度,例如

      TS654: Numeric Precision 101

      如果这是一个字符代码,最好将其保留为字符变量。

      【讨论】:

      • 虽然这是一个正确的答案,但太多的信息存储在链接后面。更好的答案是在答案中包含相关信息(例如最大存储数量)。
      • 感谢您的评论。有趣的是在不同的网站上看到不同的文化(我最熟悉 SAS-L)会记住这一点。用这样的链接猜测简短的响应会更好,因为这里的 cmets。
      • 在您有时间解释它们之前,不应发布带有链接的简短回复。评论是为了澄清问题。
      猜你喜欢
      • 2014-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 2014-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多