Merge branch 'MDL-31837_23' of git://github.com/timhunt/moodle into MOODLE_23_STABLE

This commit is contained in:
Aparup Banerjee
2012-08-28 17:04:19 +08:00
2 changed files with 42 additions and 8 deletions
+5 -3
View File
@@ -320,10 +320,13 @@ class qtype_numerical_answer extends question_answer {
throw new coding_exception('Cannot work out tolerance interval for answer *.');
}
// Smallest number that, when added to 1, is different from 1.
$epsilon = pow(10, -1 * ini_get('precision'));
// We need to add a tiny fraction depending on the set precision to make
// the comparison work correctly, otherwise seemingly equal values can
// yield false. See MDL-3225.
$tolerance = (float) $this->tolerance + pow(10, -1 * ini_get('precision'));
$tolerance = abs($this->tolerance) + $epsilon;
switch ($this->tolerancetype) {
case 1: case 'relative':
@@ -331,8 +334,7 @@ class qtype_numerical_answer extends question_answer {
return array($this->answer - $range, $this->answer + $range);
case 2: case 'nominal':
$tolerance = $this->tolerance + pow(10, -1 * ini_get('precision')) *
max(1, abs($this->answer));
$tolerance = $this->tolerance + $epsilon * max(abs($this->tolerance), abs($this->answer), $epsilon);
return array($this->answer - $tolerance, $this->answer + $tolerance);
case 3: case 'geometric':
+37 -5
View File
@@ -25,8 +25,10 @@
*/
global $CFG;
require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
require_once($CFG->dirroot . '/question/type/numerical/question.php');
class qtype_numerical_answer_test extends advanced_testcase {
public function test_within_tolerance_nominal() {
$answer = new qtype_numerical_answer(13, 7.0, 1.0, '', FORMAT_MOODLE, 1.0);
@@ -38,16 +40,46 @@ class qtype_numerical_answer_test extends advanced_testcase {
$this->assertFalse($answer->within_tolerance(8.01));
}
public function test_within_tolerance_nominal_zero() {
// Either an answer or tolerance of 0 requires special care. We still
// don't want to end up comparing two floats for absolute equality.
// Zero tol, non-zero answer.
$answer = new qtype_numerical_answer(13, 1e-20, 1.0, '', FORMAT_MOODLE, 0.0);
$this->assertFalse($answer->within_tolerance(0.9999999e-20));
$this->assertTrue($answer->within_tolerance(1e-20));
$this->assertFalse($answer->within_tolerance(1.0000001e-20));
// Non-zero tol, zero answer.
$answer = new qtype_numerical_answer(13, 0.0, 1.0, '', FORMAT_MOODLE, 1e-24);
$this->assertFalse($answer->within_tolerance(-2e-24));
$this->assertTrue($answer->within_tolerance(-1e-24));
$this->assertTrue($answer->within_tolerance(0));
$this->assertTrue($answer->within_tolerance(1e-24));
$this->assertFalse($answer->within_tolerance(2e-24));
// Zero tol, zero answer.
$answer = new qtype_numerical_answer(13, 0.0, 1.0, '', FORMAT_MOODLE, 1e-24);
$this->assertFalse($answer->within_tolerance(-1e-20));
$this->assertTrue($answer->within_tolerance(-1e-35));
$this->assertTrue($answer->within_tolerance(0));
$this->assertTrue($answer->within_tolerance(1e-35));
$this->assertFalse($answer->within_tolerance(1e-20));
// Non-zero tol, non-zero answer.
$answer = new qtype_numerical_answer(13, 1e-20, 1.0, '', FORMAT_MOODLE, 1e-24);
$this->assertFalse($answer->within_tolerance(1.0002e-20));
$this->assertTrue($answer->within_tolerance(1.0001e-20));
$this->assertTrue($answer->within_tolerance(1e-20));
$this->assertTrue($answer->within_tolerance(1.0001e-20));
$this->assertFalse($answer->within_tolerance(1.0002e-20));
}
public function test_within_tolerance_blank() {
$answer = new qtype_numerical_answer(13, 1234, 1.0, '', FORMAT_MOODLE, '');
$this->assertTrue($answer->within_tolerance(1234));
$this->assertFalse($answer->within_tolerance(1234.000001));
$this->assertFalse($answer->within_tolerance(0));
$answer = new qtype_numerical_answer(13, 0, 1.0, '', FORMAT_MOODLE, '');
$this->assertTrue($answer->within_tolerance(0));
$this->assertFalse($answer->within_tolerance(pow(10, -1 * ini_get('precision') + 1)));
$this->assertTrue($answer->within_tolerance(pow(10, -1 * ini_get('precision'))));
}
public function test_within_tolerance_relative() {