[R] number of decimal places in a number?

Joshua Wiley jwiley.psych at gmail.com
Sat Jul 7 12:44:55 CEST 2012

```Hi Martin,

Ted is spot on about the binary representation.  A very different
approach from his would be to convert to character and use regular
expressions:

## the example numbers in a vector
x <- c(3.14, 3.142, 3.1400, 123456.123456789, 123456789.123456789, pi, sqrt(2))

nchar(gsub("(.*\\.)|([0]*\$)", "", as.character(x)))

which for me returns:
[1]  2  3  2  9  6 14 13

an advantage of this approach is that for numbers like
123456789.123456789, although R cannot represent it properly as a
binary number, the character string is totally fine.

nchar(gsub("(.*\\.)|([0]*\$)", "", "123456789.123456789"))

returns 9

Essentially the expression looks for anything (the period) zero or
more times (the *) followed by an actual period (the \\.) OR 0
repeated zero or more times at the end of the string, and replaces all
of those with nothing (the "") and then returns the result, the number
of characters of which is counted by nchar()

See ?regex for details

Cheers,

Josh

On Sat, Jul 7, 2012 at 3:04 AM, Ted Harding <Ted.Harding at wlandres.net> wrote:
> On 07-Jul-2012 08:52:35 Martin Ivanov wrote:
>>  Dear R users,
>>
>> I need a function that gets a number and returns its number of
>> actual decimal places.
>> For example f(3.14) should return 2, f(3.142) should return 3,
>> f(3.1400) should also return 2 and so on. Is such function already
>> available in R? If not, could you give me a hint how to achieve that?
>>
>> Many thanks in advance.
>
> I'm not aware of such a function in R. In any case, it will be
> a tricky question to solve in full generality, since R stores
> numbers internally in a binary representation and the exact
> conversion of this representation to a decimal number may not
> match the exact value of the decimal representation of the
> original number.
>
> In particular, a number entered as a decimal representation
> from the keyboard, or read as such from a text file, may not
> be exactly matched by the internal representation in R.
>
> However, that said, the following function definition seems to
> do what you are asking for, for cases such as you list:
>
> f<-function(x) {min(which( x*10^(0:20)==floor(x*10^(0:20)) )) - 1}
>
>   f(3.14)
>   # [1] 2
>   f(3.142)
>   # [1] 3
>   f(3.1400)
>   # [1] 2
>
>
>
> Note, however:
>
>   f(123456.123456789)
>   # [1] 9
>
>   f(123456789.123456789)
>   #[1] 7
>
> (a consequence of the fact that R does not have enough binary
> digits in its binary representation to accommodate the precision
> in all the decimal digits of 123456789.123456789 -- not that it
> can do that exactly anyway in binary, no matter how many binary
> digits it had available).
>
> Similarly:
>
>   f(pi)
>   # [1] 15
>   f(sqrt(2))
>   # [1] 16
>
> which is a consequence of the fact that 2 < pi < 4, while
> 1 < sqrt(2) < 2, so the binary representation of pi needs
> 1 more binary digit for its integer part than sqrt(2) does,
> which it therefore has to "steal" from the fractional part.
>
> Hoping this helps,
> Ted.
>
> -------------------------------------------------
> E-Mail: (Ted Harding) <Ted.Harding at wlandres.net>
> Date: 07-Jul-2012  Time: 11:04:26
> This message was sent by XFMail
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

--
Joshua Wiley
Ph.D. Student, Health Psychology
Programmer Analyst II, Statistical Consulting Group
University of California, Los Angeles
https://joshuawiley.com/

```