Statalist The Stata Listserver


[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

RE: st: RE: rounding in STATA


From   "Siyam, Amani" <siyama@who.int>
To   <statalist@hsphsun2.harvard.edu>
Subject   RE: st: RE: rounding in STATA
Date   Fri, 21 Apr 2006 16:16:48 +0200

Dear Stata-listers,

Apologies for the delayed reply and my thanks to Nick, Austin and
Maarten for their thoughts on my query regarding the rounding function
in Stata.

Not sure why but when I declared the original variable (x) as "double"
rather than "float", Stata gave me the rounding that I wanted for y
(i.e. 8.750 = 8.8 to 1 decimal place). 

Thanks again for your help.

Amani




-----Original Message-----
From: owner-statalist@hsphsun2.harvard.edu
[mailto:owner-statalist@hsphsun2.harvard.edu] On Behalf Of Nick Cox
Sent: 13 April 2006 16:34
To: statalist@hsphsun2.harvard.edu
Subject: RE: st: RE: rounding in STATA

Which bit? There are 32 to play with here. 

(The rest of the discussion seems to support me, 
not contradict me, as it outlines a fudge that
admittedly sometimes is going to give the wrong answer.) 

Nick 
n.j.cox@durham.ac.uk 


Austin Nichols
 
> Amani--
> 
> All of what Nick says is true, but the claim that "there is no way you
> can avoid this kind of problem by writing your own program, unless you
> also construct a decimal-based computer" is overreaching a bit. 


-----Original Message-----
From: owner-statalist@hsphsun2.harvard.edu
[mailto:owner-statalist@hsphsun2.harvard.edu] On Behalf Of Austin
Nichols
Sent: 13 April 2006 16:15
To: statalist@hsphsun2.harvard.edu
Subject: Re: st: RE: rounding in STATA

Amani--

All of what Nick says is true, but the claim that "there is no way you
can avoid this kind of problem by writing your own program, unless you
also construct a decimal-based computer" is overreaching a bit. It's
true that the general problem of numerical precision is unavoidable,
but the specific problem you want to address is not.  If you want to
force the incorrect behavior you seem to want (rounding 8.64999999999
to 8.7) there is a way to do it.  If you are representing your numbers
as having 2 digits after the decimal point, and you believe that such
a representation is true and the more accurate binary representation
is not, then you can force the rounding you want by treating your
representation as a string--but you could be introducing error in any
setting where your homemade rounding method does not match the
binary-based rounding done by your computer.

. clear
. set obs 100
. gen obs=_n/100
. gen real=round(obs, .1)
. gen silly=round(real(string(obs*100, "%4.0f")),10)/100
. li in 64/66

     +--------------------+
     | obs   real   silly |
     |--------------------|
 64. | .64     .6      .6 |
 65. | .65     .6      .7 |
 66. | .66     .7      .7 |
     +--------------------+

Your original post raises the question of how you got the numerical 
8.75 so that you know the decimal representation is exact, but the
computer doesn't (did you do a whole series of calculations that
should result in exactly 35/4 but instead results in a close, but not
close enough, approximation?)  If so, you can turn your calculation on
integers like X into calculations using integers by using an
appropriate factor, such as 4X or 40X or 100X, and get the "right"
answer (but the appropriate factor to apply before and after the
intermediate calculations to preserve accuracy will depend on what the
intermediate calculations are).  Bear in mind always that

. di round(35/4,.1)
8.8

gives you the answer you seem to want, and you should be able to get
there from here.

--Austin

On 4/13/06, Nick Cox <n.j.cox@durham.ac.uk> wrote:
> I can't speak about STATA. In Stata, which behaves
> similarly in this instance, you can get rounding up
> by using -ceil()-.
>
> But note that you will find it difficult to avoid
> small (apparent) anomalies whatever you do.
>
> This because, in general, multiples of 0.1 cannot
> be held exactly in binary, as explained many, many
> times on this list.
>
> Suppose I have 8.75 (meaning, precisely, 8 + 3/4).
>
> Stata can hold that, _exactly_. In decimal,
>
> . di %23.18f 8.750
>    8.750000000000000000
>
> or, more to the point, in hexadecimal,
>
> . di %21x 8.750
> +1.1800000000000X+003
>
> If I round that, Stata starts to struggle:
>
> . di %21x round(8.750, 0.1)
> +1.199999999999aX+003
>
> . di %23.18f round(8.75,0.1)
>    8.800000000000000700
>
> This raises the question of what, exactly, is
> the number you are showing us which is (which
> is represented as!) 8.750. Your number is,
> I surmise, not exactly 8.750, as if it were
> it would round to 8.8.
>
> That said, there is no way you can avoid this kind of
> problem by writing your own program, unless
> you also construct a decimal-based computer.
>
> Nick
> n.j.cox@durham.ac.uk
>
> Siyam, Amani
>
> > I have a minor issue with the way STATA is rounding, for example a
> > variable to one decimal place.
> >
> > I used the command
> >
> > gen x=round(y, 0.1)
> >
> > Comparing the two variables, I noticed the that when:
> >
> >    x=                   y=
> >
> >  8.750                 8.7
> >  5.752                 5.8
> > 23.256                23.3
> >
> > Is there a way I can modify the function to round "x"=8.750 to be
8.8
> >
> > Or should I put together my own code to get the rounding I want.

-----Original Message-----
From: owner-statalist@hsphsun2.harvard.edu
[mailto:owner-statalist@hsphsun2.harvard.edu] On Behalf Of Maarten Buis
Sent: 13 April 2006 16:16
To: statalist@hsphsun2.harvard.edu
Subject: st: RE: RE: RE: rounding in STATA

Amani:
My example shows that it doesn't happen whenever you have 50 after the
decimal point. My best guess is there are more decimals in your data
than are displayed, leading you to believe that 8.750 is "exact". Try
change the format and look at the variable again, like the example
below:
format x %23.18f
list x in 1/10

HTH,
Maarten

-----------------------------------------
Maarten L. Buis
Department of Social Research Methodology 
Vrije Universiteit Amsterdam 
Boelelaan 1081 
1081 HV Amsterdam 
The Netherlands

visiting adress:
Buitenveldertselaan 3 (Metropolitan), room Z214 

+31 20 5986715

http://home.fsw.vu.nl/m.buis/
-----------------------------------------

-----Original Message-----
From: owner-statalist@hsphsun2.harvard.edu
[mailto:owner-statalist@hsphsun2.harvard.edu] On Behalf Of Siyam, Amani
Sent: 13 April 2006 15:51
To: statalist@hsphsun2.harvard.edu
Subject: st: RE: RE: RE: RE: rounding in STATA

sorry my mistake, 

the command line should read
gen y=round(x, 0.1)

y is what I got after that.

Thanks again.

Amani

-----Original Message-----
From: owner-statalist@hsphsun2.harvard.edu
[mailto:owner-statalist@hsphsun2.harvard.edu] On Behalf Of Nick Cox
Sent: 13 April 2006 15:47
To: statalist@hsphsun2.harvard.edu
Subject: st: RE: RE: RE: rounding in STATA

Another reason for not trusting your example
is that you claim to show us the results of

gen x = round(y, 0.1) 

but in your output it is y that is rounded
and x that is coarse. So, evidently you changed 
something before showing us your results. 

Nick 
n.j.cox@durham.ac.uk 

-----Original Message-----
From: owner-statalist@hsphsun2.harvard.edu
[mailto:owner-statalist@hsphsun2.harvard.edu] On Behalf Of Siyam, Amani
Sent: 13 April 2006 15:35
To: statalist@hsphsun2.harvard.edu
Subject: st: RE: RE: rounding in STATA

Thanks for your reply Maarten, the values of x are exact ones and that
happens whenever you have "50" after the decimal you are cutting, for
example 0.*50, for the one decimal place, 0.**50 for the two decimal
place...etc.

Thanks for you help in advance.

Amani
-----Original Message-----
From: owner-statalist@hsphsun2.harvard.edu
[mailto:owner-statalist@hsphsun2.harvard.edu] On Behalf Of Maarten Buis
Sent: 13 April 2006 15:14
To: statalist@hsphsun2.harvard.edu
Subject: st: RE: rounding in STATA

Amani:

Stata 8.2 doesn't show this behaviour:

. input x 

             x
  1. 8.750
  2. 5.752
  3. 23.256
  4. end

. gen y = round(x, 0.1)

. list

     +---------------+
     |      x      y |
     |---------------|
  1. |   8.75    8.8 |
  2. |  5.752    5.8 |
  3. | 23.256   23.3 |
     +---------------+


Maybe 8.750 in your data is actually 8.7499?

HTH,
Maarten


-----------------------------------------
Maarten L. Buis
Department of Social Research Methodology 
Vrije Universiteit Amsterdam 
Boelelaan 1081 
1081 HV Amsterdam 
The Netherlands

visiting adress:
Buitenveldertselaan 3 (Metropolitan), room Z214 

+31 20 5986715

http://home.fsw.vu.nl/m.buis/
-----------------------------------------

-----Original Message-----
From: owner-statalist@hsphsun2.harvard.edu
[mailto:owner-statalist@hsphsun2.harvard.edu]On Behalf Of Siyam, Amani
Sent: donderdag 13 april 2006 15:05
To: statalist@hsphsun2.harvard.edu
Subject: st: rounding in STATA


I have a minor issue with the way STATA is rounding, for example a
variable to one decimal place.

I used the command

gen x=round(y, 0.1)

Comparing the two variables, I noticed the that when:

   x=                     y=

 8.750           8.7
 5.752           5.8
23.256          23.3

Is there a way I can modify the function to round "x"=8.750 to be 8.8

Or should I put together my own code to get the rounding I want.

 

-----Original Message-----
From: owner-statalist@hsphsun2.harvard.edu
[mailto:owner-statalist@hsphsun2.harvard.edu] On Behalf Of Siyam, Amani
Sent: 13 April 2006 15:05
To: statalist@hsphsun2.harvard.edu
Subject: st: rounding in STATA

Dear Stata-listers

I have a minor issue with the way STATA is rounding, for example a
variable to one decimal place.

I used the command

gen x=round(y, 0.1)

Comparing the two variables, I noticed the that when:

   x=			  y=

 8.750		 8.7
 5.752		 5.8
23.256		23.3

Is there a way I can modify the function to round "x"=8.750 to be 8.8

Or should I put together my own code to get the rounding I want.

Many thanks in advance...


Amani

*
*   For searches and help try:
*   http://www.stata.com/support/faqs/res/findit.html
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2014 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index