BookmarkSubscribeRSS Feed
AIO
Calcite | Level 5 AIO
Calcite | Level 5

I understand that SAS performs arithmetic in a binary system, but I still have following questions about it:

  1. Variable X1 X2: since variable flag="Y", x1 should be less than x2. However, when variable x1 and x2 are displayed as best32. format,  it's "73.75". How could I find the difference directly except using HEXw. format? Is there a way that let X1 display as "73.7499999999999999999999999999999999"?
  2. Variable Z1 Z2: actually, x1 should be less than 73.75. It's specified that "When the value to be rounded is approximately halfway between two multiples of the rounding unit, the ROUND function rounds up the absolute value and restores the original sign" in ROUND function. In this case, it should be 73.7 when I use ROUND function to keep 1 decimal place. However, Z1 is 73.8, why?
  3. ⁠Variable W1 W2: I want to know what's rule when using PUT function to keep the decimal place? Is it "When the value to be rounded is approximately halfway between two multiples of the rounding unit, the ROUND function rounds up the absolute value and restores the original sign"? 
data test;
	x1=(36.9-31)*12.5;
	x2=73.75;
	if x1 <x2 then flag="Y";

	y1=x1;
	y2=x2;
	format x1 x2 best32. y1 y2 hex16.;

	z1=round(x1,0.1);
	z2=round(x2,0.1);

	w1=strip(put(x1,5.1));
	w2=strip(put(x2,5.1));
run;

 

1 REPLY 1
Ksharp
Super User

1)

For your first question, sas is unable to store 73.75 exactly in computer sometimes, so you can't always expect the expression is equal. If you want to compare them ,the best way is using ROUND() function.

if you need to display "73.7499999999999999999999999999999999" , you need to resort to PICTURE format.

proc format;
picture fmt
low-high='09.99999999999999'
;
run;

data test;
	x1=(36.9-31)*12.5;
	x2=73.75;
	if x1 <x2 then flag="Y";
put x1=  fmt32.20 x2= fmt32.20  flag=;

    call missing(flag);
	if round(x1,0.1) <round(x2,0.1) then flag="Y";
put x1=  32.20 x2= 32.20 flag=;



    z1=round(x1,0.1);
	z2=round(x2,0.1);
put z1=  32.20 z2= 32.20;

    w1=strip(put(x1,5.1));
	w2=strip(put(x2,5.1));
put w1= w2=;
run;
x1=73.74999999999999 x2=73.75000000000000 flag=Y
x1=73.75000000000000000000 x2=73.75000000000000000000 flag=
z1=73.80000000000000000000 z2=73.80000000000000000000
w1=73.7 w2=73.8
NOTE: 数据集 WORK.TEST 有 1 个观测和 7 个变量。
NOTE: “DATA 语句”所用时间(总处理时间):
      实际时间          0.03 秒
      CPU 时间          0.03 秒

2)

For your second question, in sas there is a constant epsolon:

406  data _null_;
407  ep=constant('MACEPS');
408  put ep=;
409  run;

ep=2.220446E-16

Once the difference of two numbers is less than epsolon, then sas would take these two number are same, your situation is this.

 

3) 

For your third question, I also get surprise at this result. I also think 

put(x1,5.1)

would be like this

put(round(x1,5.1),5.1)

and would expect both are 73.8 . Not one is 73.7 and another is 73.8 .

I suggest you to contact with  SAS -Technical -Support to discover what is wrong with PUT() .

Catch up on SAS Innovate 2026

Nearly 200 sessions are now available on demand in the Innovate Hub.

Watch Now →
How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 1 reply
  • 35 views
  • 0 likes
  • 2 in conversation