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;
main::prfmt($self->value,"%.".$self->{decimals}."f");
}
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(@_)};
1;
```

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:

```
DOCUMENT();
loadMacros(
"PGstandard.pl",
"Parser.pl",
);
TEXT(beginproblem());
Context("LimitedNumeric");
loadMacros("fixedPrecision.pl"); # must come after Context is set.
$n = FixedPrecision(sqrt(2),3);
BEGIN_TEXT
\($n\) = \{ans_rule(10)\}
END_TEXT
ANS($n->cmp);
ENDDOCUMENT();
```

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.

Davide