Ask Your Question

Help with "chop" and "rounding"

asked 2020-12-20 16:20:11 -0600

Eva gravatar image

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 flag offensive close merge delete


Would you mind defining "chop" ?

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2020-12-21 14:25:50 -0600 )edit

Link for the earlier question and answer mentioned in the question:

(easily found by typing "chop" in Ask Sage's "search or ask your question" box).

slelievre gravatar imageslelievre ( 2020-12-21 15:50:43 -0600 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2020-12-21 15:48:30 -0600

slelievre gravatar image

Recommended reading:

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 $$


$$ 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(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.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2020-12-20 16:17:35 -0600

Seen: 51 times

Last updated: Dec 21 '20