# Help with "chop" and "rounding"

I would like to be able to implement the equivalent of a "chop" as well as a specified rounding arithmetic in Sage in order to explore relative error in approximation of these floating point mathematical manipulations.

In particular, I'd like to write my own short functions that can demonstrate these simple concepts. As I am a relative newbie, I'd appreciate any insight.

As an example, I want to compare and contrast floating point arithmetic for (1) exact, (2) using three-digit chopping and (3) three digit rounding. Then I want to compute relative errors.

My specific question, though really is how can I implement a "chop" function in Sage? Any insight would be appreciated. I see there is an earlier response about the equivalent of Mathematica's chop function in Sage, but I'd like more help.

edit retag close merge delete

Sort by » oldest newest most voted

Some ideas:

• use RealField(k) for reals with k bits of precision
• use Arb for arbitrary precision, via RealBallField or ComplexBallField

Chopping (also know as truncating) might mean different things:

• truncate the binary or decimal expansion?
• absolute or relative precision, i.e. do you truncate to base^-N or does it depend on the size of the number?

For example, truncating the following numbers to 2 decimal places:

$$a = 23456.789$$ $$b = 2.3456789$$ $$c = 0.00023456789$$

do you expect the result to be

$$a' = 23456.78$$ $$b' = 2.34$$ $$c' = 0.0$$

or

$$a' = 23000.00$$ $$b' = 2.3$$ $$c' = 0.0023$$

?

The following function could be a starting point:

def chop(x, precision=3, base=10, absolute=True):
bp = base^precision
if absolute:
return RDF(floor(bp*x)/bp)
# otherwise truncate to relative precision
size = floor(log(x, base)) + 1
bs = base^size
return chop(x/bs, precision=precision, base=base, absolute=True)*bs


Define a printing and formatting function for illustration:

def chop_list(aa):
format = "%20s %20s %20s"
print()
print(format % ('number', 'chop_absolute', 'chop_relative'))
for a in aa:
b = chop(a, precision=2, base=10, absolute=True)
c = chop(a, precision=2, base=10, absolute=False)
print("%20s %20s %20s" % (a, b, c))


Check out the results:

sage: aa = [23456.789, 2.3456789, 0.0023456789]
sage: chop_list(aa)

number        chop_absolute        chop_relative
23456.7890000000             23456.78              23000.0
2.34567890000000                 2.34   2.3000000000000003
0.00234567890000000                  0.0               0.0023


Now for rounding instead of truncating, use round instead of floor.

more