[R] Single precision data behaviour with readBin()
Henrik Bengtsson
hb at stat.berkeley.edu
Thu Nov 9 22:43:18 CET 2006
Hi,
what you are observing is the fact that there is always a limit in the
precision a floating-point values can be stored. The value you are
trying to read is stored in 4 bytes (floats). For higher precision,
the value could be stored in 8 bytes (doubles). BTW, R works with 8
byte floating-toint values. Example illustrating this (R --vanilla):
# Write data
> x <- 0.05
> writeBin(x, con="float.bin", size=4)
> writeBin(x, con="double.bin", size=8)
# Read data
> yF <- readBin("float.bin", what="double", size=4)
> yD <- readBin("double.bin", what="double", size=8)
# Display data with different precisions
> options(digits=7) # Default in R (unless you change it)
> getOption("digits")
[1] 7
> yF
[1] 0.05
> yD
[1] 0.05
> options(digits=8)
> yF
[1] 0.050000001
> yD
[1] 0.05
> options(digits=12)
> yF
[1] 0.0500000007451
> yD
[1] 0.05
# Difference between 0.5 stored as double and float
> log10(abs(yD-yF))
[1] -9.12780988455
# Eventually you will see the same for doubles too:
options(digits=22)
> 1e-24
[1] 9.99999999999999924e-25
Hope this helps!
Henrik
On 11/10/06, Eric Thompson <eric.thompson at tufts.edu> wrote:
> Hi all,
>
> I am running R version 2.4.0 (2006-10-03) on an i686 pc with Mandrake
> 10.2 Linux. I was given a binary data file containing single precision
> numbers that I would like to read into R. In a previous posting,
> someone suggested reading in such data as double(), which is what I've
> tried:
>
> > zz <- file(file, "rb")
> > h1 <- readBin(con = zz, what = double(), n = 1, size = 4)
> > h1
> [1] 0.0500000007451
>
> Except that I know that the first value should be exactly 0.05. To get
> rid of the unwanted (or really unknown) values, I try using signif(),
> which gives me:
>
> > h1 <- signif(h1, digits = 8)
> > h1
> [1] 0.050000001
>
> I suppose I could use:
>
> > h1 <- signif(h1, digits = 7)
> > h1
> [1] 0.05
>
> But this does not seem ideal to me. Apparently I don't understand
> machine precision very well, because I don't understand where the
> extra values are coming from. So I also don't know if this use of
> signif() will be reliable for all possible values. What about a value
> of 1.2e-8? Will this be read in as:
>
> > signif(1.200000000034e-8, digits = 7)
> [1] 1.2e-08
>
> or could this occur?:
>
> > signif(1.2000034e-8, digits = 7)
> [1] 1.200003e-08
>
> Thanks for any advice.
>
> Eric Thompson
> Graduate Student
> Tufts University
> Civil & Environmental Engineering
> Medford, MA 02144
>
> ______________________________________________
> R-help at stat.math.ethz.ch 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.
>
More information about the R-help
mailing list