# Modifying the value of a float-like object

Peter Otten __peter__ at web.de
Wed Apr 15 09:51:52 CEST 2009

```Eric.Le.Bigot at spectro.jussieu.fr wrote:

> Now, I would like to get the uncertainty on the result, even though we
> have no idea of what quantities are used in lattice_spacing() for the
> calculation (it can be attribute that are floats, attributes that are
> FloatWithUncert, module globals defined as FloatWithUncert, etc.).

I think this is your main problem. What you describe is a source of hard to
find bugs and a maintenance nightmare.

I also don't understand what you want to do with the results. Consider a
simple example

a = 1 +- 0.1
b = 1 +- 0.1

Now let's calculate a + b. With my approach you get

a + b = 2 +- 0.14

i. e. the result falls in the interval 1.86...2.14 with the same likelihood
that a and b are within 0.9...1.1. You don't get 2 +- 0.2 because the
errors sometimes cancel out.

With your approach you get (some permutation of)

a + b = [1.9, 1.9, 2.0, 2.0, 2.1, 2.1]

What is that supposed to mean? Let's assume you have one additional variable

c = 42 +- 7 # whatever

a + b = [1.9, 1.9, 2.0, 2.0, 2.0, 2.0, 2.0, 2.1, 2.1]

Hmm...

Here's the code I used to get that result:

class F(object):
all = []
def __init__(self, value, err):
self.value = value
self.err = err
self.shift = 0
self.all.append(self)

def __float__(self):
return self.value + self.err * self.shift

return float(self) + float(other)
def __mul__(self, other):
return float(self) * float(other)
__rmul__ = __mul__

def __str__(self):
return "F(%s)" % float(self)

a = F(1.0, 0.1)
b = F(1.0, 0.1)
unused = F(42.0, 7.0)

results = []
for f in F.all:
for f.shift in [-1, 0, 1]:
print "a = %s, b = %s, a+b = %s" % (a, b, a + b)
results.append(a+b)
f.shift = 0
print "[%s]" % ", ".join("%.1f" % r for r in sorted(results))

If you add enough arithmetic operations it might even "work" with your
codebase.

Peter

```