Same function with same inputs returns different values

ozgeneral

Lets say I have a function like follows:

testFunction <- function(testInputs){
    print( sum(testInputs)+1 == 2 )
    return( sum(testInputs) == 1 )
}

When I test this on command line with following input: c(0.65, 0.3, 0.05), it prints and returns TRUE as expected.

However when I use c(1-0.3-0.05, 0.3, 0.05) I get TRUE printed and FALSE returned. Which makes no sense because it means sum(testInputs)+1 is 2 but sum(testInputs) is not 1.

Here is what I think: Somehow printed value is not exactly 1 but probably 0.9999999..., and its rounded up on display. But this is only a guess. How does this work exactly?

De Novo

This is exactly a floating point problem, but the interesting thing about it for me is how it demonstrates that the return value of sum() produces this error, but with + you don't get it.

See the links about floating point math in the comments. Here is how to deal with it:

sum(1-0.3-0.5, 0.3, 0.05) == 1
# [1] FALSE
dplyr::near(sum(1-0.3-0.05, 0.3, 0.05), 1)
# [1] TRUE

For me, the fascinating thing is:

(1 - 0.3 - 0.05 + 0.3 + 0.05) == 1
# [1] TRUE

Because you can't predict how the various implementations of floating point arithmetic will behave, you need to correct for it. Here, instead of using ==, use dplyr::near(). This problem (floating point math is inexact, and also unpredictable), is found across languages. Different implementations within a language will result in different floating point errors.

As I discussed in this answer to another floating point question, dplyr::near(), like all.equal(), has a tolerance argument, here tol. It is set to .Machine$double.eps^0.5, by default. .Machine$double.eps is the smallest number that your machine can add to 1 and be able to distinguish it from 1. It's not exact, but it's on that order of magnitude. Taking the square root makes it a little bigger than that, and allows you to identify exactly those values that are off by an amount that would make a failed test for equality likely to be a floating point error.

NOTE: yes, near() is in dplyr, which i almost always have loaded, so I forgot it wasn't in base... you could use all.equal(), but look at the source code of near(). It's exactly what you need, and nothing you don't:

near
# function (x, y, tol = .Machine$double.eps^0.5) 
# {
#     abs(x - y) < tol
# }
# <environment: namespace:dplyr>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

The same PL/SQL function returns two different values

Pytorch BCELoss function different outputs for same inputs

Why GetDC returns different values for the same object?

Same xpath returns different values on Centos, Ubuntu

SuperFastHash returns different values for the same string

Same function shows different values at different places

Predict different values from same inputs in a linear regressor model?

Php function returns the same with different parameters

The function returns different answers for the same given

Why glGetSubroutineIndex returns the same value for different function?

Python function returns the same output with different parameters

Function returning different result despite the same inputs in Python

Checking different lengths of several inputs fields in the same function

The same function always returns different answers for the same input

jQuery - Check if values of inputs, textareas and select not blank in same function

5 different Objects with the same values to an function

Using same swift UIlabels for different function values

how to mock different values for same function jest?

Same function within different files returns different results

md5sum returns different values with "same" strings

Why Objects.hash() returns different values for the same input?

MongoDB returns different values from count() and find() for same filters

Golang: sha256 returns two different values for the same input

Excel between times returns different values in same range

Postgresql ORDER_BY ... COLLATE with different values returns same output

Why SIZE_OF_STR returns 2 different answers for the same values?

How to mock the same function called in different components with different returned values

Lisp: same mathematical function evaluates to different values at different time?

How to compare two different values of different functions or same function?