Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stata seemingly not actually rounding with round()

Tags:

rounding

stata

Stata has a round() function. One can select the units it rounds to. I want to round an arbitrary floating point value to two decimal places using round(ArbitraryValue, 0.01). Stata's display seems to understand this. But somehow the internal representation of round(ArbitraryValue, 0.01) still has the unrounded floating point value:

. local LevelA = 99.98765432123321

. ttest mpg==20, level(`LevelA') <BR>
level() can have at most two digits after the decimal point <BR>
r(198);

. local LevelB = round(`LevelA',0.01)

. di `LevelB' <BR>
99.99

. ttest mpg==20, level(`LevelB') <BR>
level() must be between 10 and 99.99 inclusive <BR>
r(198);

. set trace on

. ttest mpg==20, level(`LevelB') <BR>

[SNIP]<BR>
 = local 0 mpg = 20, level(**99.99000000000001**) <BR>
[SNIP] <BR>
r(198);

What am I not understanding about how to correctly round?

like image 704
Alexis Avatar asked Mar 15 '23 07:03

Alexis


1 Answers

You are being bitten by a basic fact. You want to see exact decimals, but Stata doesn't use exact decimals here; it necessarily calculates in binary. Much ingenuity at several levels hides this from you most of the time, but occasionally it breaks through to the surface.

round() can't possibly find an exact binary representation of 99.99 because there isn't one. The same applies to any multiple or fraction of 0.1(0.1)0.9 except for some multiples or fractions of 0.5.

In that sense, only exceptionally can round() do what you expect, produce an exact multiple of 0.01.

The calculations induced by display are not an exception to this principle; it's just that default display formats usually hide the ugly truth from you.

What you want is in fact a string manipulation, namely display with a specified format such as %3.2f which will guarantee that Stata thinks it is seeing two decimal places.

. sysuse auto, clear
(1978 Automobile Data)

. local LevelA = 99.98765432123321

. local myLevelA : di %3.2f `LevelA'

. ttest mpg == 20, level(`mylevelA')

One-sample t test
------------------------------------------------------------------------------
Variable |     Obs        Mean    Std. Err.   Std. Dev.   [95% Conf. Interval]
---------+--------------------------------------------------------------------
     mpg |      74     21.2973    .6725511    5.785503     19.9569    22.63769
------------------------------------------------------------------------------
    mean = mean(mpg)                                              t =   1.9289
Ho: mean = 20                                    degrees of freedom =       73

    Ha: mean < 20               Ha: mean != 20                 Ha: mean > 20
 Pr(T < t) = 0.9712         Pr(|T| > |t|) = 0.0576          Pr(T > t) = 0.0288

search precision to find out more.

like image 177
Nick Cox Avatar answered Apr 06 '23 07:04

Nick Cox