Stata The Stata listserver
[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

st: RE: decimals stored in Float

From   "Nick Cox" <>
To   <>
Subject   st: RE: decimals stored in Float
Date   Sun, 20 Oct 2002 17:45:04 +0100
> Decimals in float are stored differently than displayed.
> Now, assume that
> variable x=0.2 and it is stored in float and displays as a
> %9.2g.  If I execute
> the command replace x=0.3 if x==0.2 no change is made.
> This is because the
> number 0.2 is stored as a number between 0.2 and 0.3 (?).
> The manual suggest to
> either write the command as replace x=0.3 if x==float(0.2),
> or to recast the
> Float into a Double.  While the first option seem to work
> fine, the second
> doesn't.  My question is: how can I get rid of the Float
> stored format and
> actually have a 0.2 recognized as a 0.2?

Ultimately, there is a crunch. Your computer works in binary, and
works in binary, and the only way for 0.2 to be recognised as 0.2
in absolutely all circumstances is to store those characters as
characters of a string variable, not much of a solution, presumably.
It is inescapable that some exact decimals do not have exact binary

Having said that, I am not clear what is not working as advertised
with your use of -float()-.

This is what I did in Stata 7:

. set obs 1
obs was 0, now 1

. gen floatpt2 = 0.2

That's a -float-, by default.

. gen double doublept2 = 0.2

That's a -double-, by request.

. format * %23.18f

That's a useful format to
get an idea of what's going on fairly deep down.

. l

                    floatpt2                doublept2
  1.    0.200000002980232240     0.200000000000000010

The approximation of -floatpt2- is clearly poorer.
Neither is perfect. Neither can be perfect.

Now if I -recast- to -double-, it is like putting the same plant
in a bigger pot, but Stata, like a careful gardener,
does not change the plant more than necessary.
I still need to use -float()- when testing:

. recast  double floatpt2

. l

                    floatpt2                doublept2
  1.    0.200000002980232240     0.200000000000000010

. list if floatpt2 == float(0.2)

                    floatpt2                doublept2
  1.    0.200000002980232240     0.200000000000000010

. list if floatpt2 == 0.2

                    floatpt2                doublept2

Note: nothing listed.

. list if doublept2  == 0.2

                    floatpt2                doublept2
  1.    0.200000002980232240     0.200000000000000010

In practice, however, whenever I want to do something like this,
it is to correct a typo or a similar mistake. Getting into the
editor and re-entering values _or_ replacing with -in- rather
than -if- means that I am never bitten by this. That is,
even though I know about -float()- I always go roundabout.
I have learned that one can get confused by this, and it
is best not to worry about it, but to use other approaches.


*   For searches and help try:

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