You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SAS中DO WHILE与DO UNTIL循环为何会在应终止后多执行一次循环体?

Understanding Your SAS DO WHILE/DO UNTIL Loop Behavior

Hey there! This is a super common gotcha with floating-point number precision—let’s break down exactly what’s happening with both of your loops.

Problem 1: DO WHILE Loop Outputting 1.1

First, let’s recap your code:

data do_while; 
    a = 0; 
    do while (a<1); 
        a = a+0.1; 
        output; 
    end; 
run;

You’d expect the loop to stop when a hits 1.0, right? Here’s why it doesn’t:

  • The value 0.1 can’t be represented exactly as a binary floating-point number (the format SAS uses for numeric variables). It’s an infinite repeating fraction in binary, so every time you add 0.1, you’re actually adding a tiny approximation of 0.1.
  • After 10 additions, instead of getting exactly 1.0, you end up with a value very slightly less than 1.0 (something like 0.9999999999999999).
  • Since this value still satisfies a<1, the loop runs one more time: a becomes 0.9999999999999999 + 0.1 = 1.0999999999999999, which SAS displays as 1.1 in your dataset. Then the loop checks a<1 again, which is false, so it terminates.

Problem 2: DO UNTIL Loop Also Outputting 1.1

Your DO UNTIL code:

data do_until; 
    b=0; 
    do until (b>=1); 
        b=b+0.1; 
        output; 
    end; 
run;

Your logic about DO UNTIL (execute first, check condition second) is totally correct—here’s why you still get 1.1:

  • Again, floating-point precision is the issue. After 9 additions, b isn’t exactly 0.9—it’s a tiny approximation slightly less than 0.9.
  • Adding 0.1 gives you a value still slightly less than 1.0 (like 0.9999999999999999). Since b>=1 is still false, the loop runs again: b becomes 1.0999999999999999 (displayed as 1.1), you output it, then the condition b>=1 finally evaluates to true, and the loop stops.

How to Fix This

To avoid floating-point precision headaches in loops like this, try one of these approaches:

  1. Loop with integers instead: Calculate your decimal value using an integer counter—this eliminates approximation errors entirely:

    data do_while_fixed;
        do i = 1 to 10;
            a = 0.1 * i;
            output;
        end;
    run;
    
  2. Use rounding in your condition: If you need to stick with decimal increments, round the value when checking the condition to account for tiny precision gaps:

    data do_while_fixed;
        a = 0;
        do while (round(a, 0.1) < 1);
            a = a + 0.1;
            output;
        end;
    run;
    

You can verify the exact stored values by adding a put statement to your original code, like put a best32.;—this will show you the full precision of the number SAS is actually using, not just the rounded display value.

内容的提问来源于stack exchange,提问作者PoorDataAnalyst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 19:22:27