How to round floating point numbers
In most Computer Assisted Testing Environments, the numbers in the problems
have been generated using random numbers, so that each student will get
his/her own version of the problem.
The idea is, of course, to encourage students to do the work themselves, rather
than just copy someone else's work.
Since the numbers will usually be floating point numbers, it is important
to be able to control the number of digits in them, so that the student
concerned about significant figures does not fall foul.
There are two aspects of the rounding problem, one of which concerns printing,
i.e., what does the student see, and the other concerns computing with rounded
numbers, to guarantee that the computer and the student are calculating
the same thing.
Here is the program which runs a test on two methods of rounding:
#!/usr/local/bin/perl -- -*- C -*-
require "round.pl";
require "round2.pl";
use CGI;
use CGI::Carp qw(fatalsToBrowser);
$query = new CGI;
$debug = 0;#1 = true
print $query->header;
print $query->start_html("round test");
print "<H1>RoundTest</H1>
";
print "<P>";
print $query->start_form;
print "<P> Enter a decimal number to be rounded", $query->textfield('t1',"",40,40);
print $query->submit;
print $query->end_form;
if($query->param('t1') ne ''){
$in_value = $query->param('t1');
$in_value =~ m/./g;
$dec_pt = pos($in_value);
$len = length($in_value);
$no_dec = $len - $dec_pt;
if(){
print "in_value = $in_value";
print "<br>loc of decimal point = $dec_pt";
print "<br>length of invalue = $len";
print "<br>number of decimal chars = $no_dec";
}
for ($count = 0;$count < $no_dec; $count++){
$v1 = round($in_value,$count);
print "<br> value returned by round($in_value,$count) = $v1";
= round2(,);
print "<br> value returned by round2($in_value,$count) = $v2";
}
}
print $query->end_html;
As you can see, this program calls two subroutines, round and round2.
Here is round:
sub round
# round of number, number of digits
{
#print "<br>in subroutine, $_[0]";
#print "<br>in subroutine, $_[1]";
return(int($_[0]*10**$_[1]) / 10**$_[1]);
}
1
and here is rounds (which actually works):
sub round2
# round of number, number of digits
{
$debug = 0;#1 = true
$value = shift || return 0;
$places = shift || 2;
if ($debug){
print "<br>in round2, arg 0 = $_[0]";
print "<br>in round2, arg 1 = $_[1]";
print "<br>in round2, value = $value";
print "<br>in round2, places = $places";
}
return sprintf "%.${places}f", $value;
}
1
and here is a link to the test
program .
You can decide on your own why my version is not quite right (I won't tell you
which is my version, and which is a WWW TechRepublic version
!).
Return to the main book TOC.