WeBWorK Problems

Significant digits in answers

Significant digits in answers

by D. Brian Walton -
Number of replies: 5
I will be assisting a colleague in writing some WW problems for a statistics class. One of the key issues that he seems to be facing is in regards to student answers. Evidently, in the context of this class, he wants students to enter answers rounded to a particular number of significant digits.

I think this is in the context of how scientific data is given to some number of digits of precision, so that when analysis is done on the data, the mathematics might give some highly accurate numerical answer, but only the original number of significant digits should actually be reported in the answer.

Has anyone already worked out clean solutions to this type of issue? To avoid completely rewriting everything, I'm leaning towards the following implementation:
1) Write a rounding function that expresses an answer, rounded to the desired number of digits.
2) Writing a function that looks at a student answer and determines the number of reported significant digits.
3) Using a custom checker that compares the student answer to the correct answer, rounded appropriately AND requires the appropriate number of significant digits.

How does this strategy sound?

- Brian
In reply to D. Brian Walton

Re: Significant digits in answers

by Paul Pearson -
Hi Brian,

You might look at the contextCurrency.pl macro for inspiration. Also, you might want to contact Davide Cervone (at Union College) about good ways to write parsers and answer checkers. My guess is that you'll want to create a MathObject "Sigfig" that would take some parameters. For example, $a = Sigfig("2.70",digits=>"3") would be a MathObject for which $a->cmp() would require the student's answer to include the trailing zero. Also, Davide may have even better suggestions for implementing something like this.

Good luck!

In reply to D. Brian Walton

Re: Significant digits in answers

by Davide Cervone -

The contextScientificNotation.pl macro file might be a better choice, as it already implements optional minimum (and maximum) required precision values.

I also remember having written a FixedPrecision class for Ken Appel. I looked it up and have attached the fixedPrecision.pl file, but also list it here.

    sub _fixedPrecision_init {}

    package FixedPrecision;
    our @ISA = ("Value::Real");

    sub new {
      my $self = shift; my $class = ref($self) || $self;
      my $context = (Value::isContext($_[0]) ? shift : $self->context);
      my $x = shift; my $n = shift;
      Value::Error("Too many arguments") if scalar(@_) > 0;
      if (defined($n)) {
        $x = main::prfmt($x,"%.${n}f");
      } else {
        $x =~ s/\s+//g;
        my ($int,$dec) = split(/\./,$x);
        $n = length($dec);
      $self = bless $self->SUPER::new($context,$x), $class;
      $self->{decimals} = $n; $self->{isValue} = 1;
      return $self;

    sub string {
      my $self = shift;

    sub compare {
      my ($self,$l,$r) = Value::checkOpOrder(@_);
      $l cmp $r;

    package FixedPrecisionNumber;
    our @ISA = ("Parser::Number");

    sub new {
      my $self = shift; my $class = ref($self) || $self;
      my $equation = shift; my $context = $equation->{context};
      $self = bless $self->SUPER::new($equation,@_), $class;
      $self->{value} = FixedPrecision->new($self->{value_string});
      return $self;

    sub string {(shift)->{value}->string(@_)}
    sub TeX {(shift)->{value}->TeX(@_)}

    package main;

    Context()->{parser}{Number} = "FixedPrecisionNumber";

    sub FixedPrecision {FixedPrecision->new(@_)};


This file defines a new MathObject class (FixedPrecision) that is a subclass of the Real class and adds a new field {decimals} that determines how many decimal places to use. It also creates a Parser class that replaces the standard Number class that uses the new FixedPrecision object to implement numbers in the Parser.

By default, FixedPrecsion(x) will take however many decimal digits there are in 'x' as the number of digits, or you can specify the number explicitly as FixedPrecision(x,digits). For example, FixedPrecision(sqrt(2),3) would produce a value 1.414 that the student must match exactly.

You should use this within the LimitedNumeric context, as in the following example:




    loadMacros("fixedPrecision.pl");  # must come after Context is set.

    $n = FixedPrecision(sqrt(2),3);

    \($n\) = \{ans_rule(10)\}



The FixedPrecision class overrides the string and compare methods to implement the fixed-precision output and to do a string comparison rather than a (fuzzy) numeric comparison, so that only the exact number of digits will be marked correct.

Note that this is not a full implementation of a MathObject class, which would have to be more sophisticated in order to handle things like addition, subtraction, and so on correctly. This means it can only be used in the LimitedNumeric context where those operations will never be performed. This class also won't handle scientific notation properly. It would be possible to make a more complete implementation of this idea, but there are details to be worked out.


In reply to D. Brian Walton

Re: Significant digits in answers

by Davide Cervone -
There is also a discussion of fixed precision issues at


that might be useful to you.
In reply to Davide Cervone

Re: Significant digits in answers

by Edward Sternin -
I would like to revive this thread. The one Davide pointed to is also stalled, and the original posting in here is precisely my problem.

In the context of teaching an introductory Physics class, where we make rigorous insistence on "garbage in, garbage out" constraint on the data, sig figs are all important, and we insist on them. In fact, even as we cross the boundary of 99 / 101 we continue to do so (i.e 99 or 1.0*10^2 must be used. We deal with a more refined error analysis later in the course, but we must build an automatic natural habit of entering only the non-bogus digits). And WeBWorK is failing us in this.

Using Davide's FixedPrecision context, one can fake the proper checking, by carefully adjusting the range of the input parameters so that the valid answer is always, say, between 10 and 99. Then setting the FixedPrecision to 1 would produce 3 sig figs, etc. This is hard work, as it requires careful editing of every problem in the library, including the limits on all parameters!

I want a generic method of checking the answer for correctness that includes a sig fig constraint.

It must do this:
(1) count the number of sig figs entered. This is non-trivial, as entries such as "5.6*10^(-3)" must be dealt with properly.
(2) establish the absolute tolerance that corresponds to the 0.5 of the value of last sig.fig.
(3) compare the numerical closeness, to within this tolerance

I think this should do it, am I forgetting anything?

Just like the original poster, I want
ANS($x->cmp, SigFigs=2)
or some such thing.

There is also the question of display. I already have to filter every random value of a parameter into FixedPrecision context before displaying --- random(3,4,0.1) produces (!) 1 sig fig numbers at the end of the interval, and 2 sig fig numbers in between --- a similar problem arises in displaying correct answers. While I have control over how I display things in the text of the problem,

$x_sf=FixedPrecision($x,1); # make sure $x=1..9.9, makes 2 s.f.

... initial position \($x_sf\) ....

But I have no control over how WebWork displays the correct answer value, so a million digits pop up, completely undermining the lesson on bogus sig figs.

So, a generic context would be preferable, so that EVERYTHING is affected in the same way. Perhaps then I will not need to carefully edit every problem from the library, just the master include macro file (I assume there is one).

The problems is, while I am not a completely incompetent coder, I am new to WebWork. For example, I do not understand Davide's suggestion of looking at the ScientificNotation context; I do not think it is quite the same thing, so perhaps Davide meant to look at how its code was written when writing a SigFigs context? To tell the truth, I do not even know where to find this code at the moment...


In reply to Edward Sternin

Re: Significant digits in answers

by Edward Sternin -
We are trying to get this issue going (that, and tikz support for dynamic figure generation).

In case someone is interested, or knows someone who is, this currently posted job can be done remotely, on a contractual basis. By law, preference will be given to Canadian citizens.

Job title
Duties: Assist in programming (in WeBWorK) a data base of physics problems for use in first-year physics courses.
Essential skills: Strong programming ability/skills; Linux experience; basic knowledge of physics

Preference will be given to candidates with:
• a strong knowledge of first-year university physics:
• experience with Perl, LaTeX, and familiarity with WeBWorK;
• experience with other scripting languages;
• experience with tikZ (a LaTeX package for graphics)

Electronic submissions including cover letter and CV to physics@brocku.ca
All applications and letters should be sent to the attention of:
Department of Physics
Brock University
1812 Isaac Brock Way
St. Catharines, ON L2S 3A1