[R] Fwd: trunc/floor a number -- strange bahaviour

Duncan Murdoch murdoch at stats.uwo.ca
Fri Feb 13 13:05:43 CET 2009


I'm glad you are happy with your solution.  Just one inline comment 
below, expanding on my private reply to you:

Žroutík wrote:
> Resolved.
>
> nchar(unlist(strsplit(as.character(n),"\\.")))[2]
>
> in the function:
> NumberPrecision <- function(n) {
> PocetCyklu <- 0
> if(n != round(n)) {
> PocetCyklu <- nchar(unlist(strsplit(n,"\\.")))[2]
> }
> else {
> while(n == round(n)) {
> n <- n/10
> PocetCyklu <- PocetCyklu + 1
> }
> PocetCyklu <- PocetCyklu - 1
> #}
> PocetCyklu
> }
>
> for 130000 the precision of the given value is the last given digit -- 5,
> for 12.345 it gives 3. Perfect.
>
> Regards, Z
>
> Thank you for the thoughtful conversation.
>
> ---------- Forwarded message ----------
> From: Žroutík <zroutik at gmail.com>
> Date: Fri, Feb 13, 2009 at 7:32 AM
> Subject: Re: [R] trunc/floor a number -- strange bahaviour
> To: Duncan Murdoch <murdoch at stats.uwo.ca>
>
>
> Thank you Duncan, and Thierry, to you, too, for the quick responses.
>
> In the FAQ, there is a different example, IMO. The value sqrt(2) is created
> by some function and is irrational -- I do understand in "never-ending"
> numbers programs do have to cut some digits off, therefore a mismatch. But
> in my example the given value is fix (it is written into an input file by a
> user) and there is always a fix number of digits and the number is not
> irrational.
>
> I do not understand how can the given/fix number 0.0001 be abruptly
> represented as 0.000099999.
>
> You say it's about binary floating point. But this is way the binary
> floating point was created, for real ending values, isn't it so?
>
> 12.34 is represented as 1234 (integer) times ten (integer) to the minus 2
> (integer). (n - floor(n))*10 Minus floor(12) (integer), times ten gives 34
> (integer) times ten to the -1 (integer).
>   

No, that's not how standard floating point representations work.  12.34 is represented as a finite precision binary number between 1 and 2 (starting out as 1.10001 in binary notation) multiplied by 2^3.  The problem is that there is no way to represent it exactly in this format.  Only fractions with a power of 2 in the denominator can be represented that way, and 12.34 is not one of those.  It's 1234/100, and 100 is not a power of 2.

Duncan Murdoch


> Is there any way how can I check on not to crush in such a problems. I
> remind you, I do not count with irrational or other "neverending" numbers.
>
> Regrads,
> Zroutik
>
>
> On Thu, Feb 12, 2009 at 4:44 PM, Duncan Murdoch <murdoch at stats.uwo.ca>wrote:
>
>   
>> On 2/12/2009 10:20 AM, Žroutík wrote:
>>
>>     
>>> Hi everybody,
>>>
>>> given a fresh rgui.exe load on winxp OS, I enter (a minimal exaple)
>>>
>>> n <- 12.357531
>>>
>>> Then the following command:
>>> n <- (n - floor(n))*10; n
>>>
>>> gives the following outputs:
>>> [1] 3.57531
>>> [1] 5.7531
>>> [1] 7.531
>>> [1] 5.31
>>> [1] 3.1
>>> [1] 1         === still as expected
>>> [1] 10        === not expected, count with me: 1 - floor(1) is zero, times
>>> 10 gives 0, not 10!!!!
>>>
>>>       
>> You are assuming that when R prints "1", the value is exactly 1.  But try
>> this:
>>
>>     
>>> 0.999999999
>>>       
>> [1] 1
>>     
>>> 0.999999999 == 1
>>>       
>> [1] FALSE
>>
>> R rounds values when it prints them, because people don't want to see ugly
>> output like this:
>>
>>     
>>> options(digits=18):
>>> n <- 12.357531
>>> n <- (n - floor(n))*10; n
>>>       
>> [1] 3.5753100
>>     
>>> n <- (n - floor(n))*10; n
>>>       
>> [1] 5.75309999999998
>>     
>>> n <- (n - floor(n))*10; n
>>>       
>> [1] 7.530999999999821
>>     
>>> n <- (n - floor(n))*10; n
>>>       
>> [1] 5.30999999999821
>>     
>>> n <- (n - floor(n))*10; n
>>>       
>> [1] 3.099999999982117
>>     
>>> n <- (n - floor(n))*10; n
>>>       
>> [1] 0.999999999821171
>>
>> And the reason you see such ugly output is because you are working with a
>> number that can't be represented exactly in binary floating point.
>>
>> Duncan Murdoch
>>
>>  [1] 10        === should stay forever zero (0)
>>     
>>> [1] 10
>>> [1] 9.999998
>>> [1] 9.999982
>>> [1] 9.999821
>>> [1] 9.998212
>>>
>>> The sama happens with trunc().
>>> e.g. (a minimal exaple)
>>>
>>> n <- 0.245
>>> n <- (n - trunc(n))*10; n
>>> [1] 2.45
>>> [1] 4.5
>>> [1] 5
>>> [1] 1.776357e-13 ===== zero expected!!!
>>> [1] 1.776357e-12
>>>
>>> And I'm asking "what the heck?!" and where is the bug in my examples? Any
>>> suggestion well appreciated.
>>>
>>> p.s. The expression with floor() and trunc() are to be implemented in a
>>> function which gives a value equal precision order of the given number.
>>> e.g.
>>> 12.345 would have (-3), 12.1 would have (-1), 12 would have (0) and e.g.
>>> 12000 would have the order of the precision (4). Basically, it is the
>>> order
>>> of the last given non-zero digit.
>>>
>>>        [[alternative HTML version deleted]]
>>>
>>> ______________________________________________
>>> 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.
>>>
>>>       
>>     
>
> 	[[alternative HTML version deleted]]
>
>   
> ------------------------------------------------------------------------
>
> ______________________________________________
> 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.
>




More information about the R-help mailing list