diff -uNr moodle.orig/question/type/calculated/questiontype.php moodle/question/type/calculated/questiontype.php
--- moodle.orig/question/type/calculated/questiontype.php	2006-04-05 06:53:23.000000000 +0100
+++ moodle/question/type/calculated/questiontype.php	2006-10-05 15:10:13.000000000 +0100
@@ -234,7 +234,7 @@
             $correctanswer = qtype_calculated_calculate_answer(
                  $answer->answer, $state->options->dataset, $answer->tolerance,
                  $answer->tolerancetype, $answer->correctanswerlength,
-                 $answer->correctanswerformat, $unit->unit);
+                 $answer->correctanswerformat, $unit->unit, 1); // paulo.matos: bug #4901
             $answer->answer = $correctanswer->answer;
         }
         $numericalquestion->questiontext = parent::substitute_variables(
@@ -709,7 +709,8 @@
 $QTYPE_MENU['calculated'] = get_string("calculated", "quiz");
 
 function qtype_calculated_calculate_answer($formula, $individualdata,
-        $tolerance, $tolerancetype, $answerlength, $answerformat='1', $unit='') {
+        $tolerance, $tolerancetype, $answerlength, $answerformat='1', $unit='',
+        $nounits=0) { //paulo.matos: bug #4901
 /// The return value has these properties:
 /// ->answer    the correct answer
 /// ->min       the lower bound for an acceptable response
@@ -730,15 +731,15 @@
                 $calculated->answer = $regs[1] . substr(
                         $regs[2] . '00000000000000000000000000000000000000000x',
                         0, $answerlength)
-                        . $unit;
+                        ;  // paulo.matos: bug #4901
             } else {
                 $calculated->answer .=
                         substr('.00000000000000000000000000000000000000000x',
-                        0, $answerlength + 1) . $unit;
+                        0, $answerlength + 1) ;  // paulo.matos: bug #4901
             }
         } else {
             /* Attach unit */
-            $calculated->answer .= $unit;
+            //$calculated->answer .= $unit;  // paulo.matos: bug #4901: done at the end
         }
 
     } else if ($answer) { // Significant figures does only apply if the result is non-zero
@@ -771,25 +772,25 @@
             $eX = 'e'.--$p10;
             $answer *= 10;
             if (1 == $answerlength) {
-                $calculated->answer = $sign.$answer.$eX.$unit;
+                $calculated->answer = $sign.$answer.$eX;  // paulo.matos: bug #4901
             } else {
                 // Attach additional zeros at the end of $answer,
                 $answer .= (1==strlen($answer) ? '.' : '')
                         . '00000000000000000000000000000000000000000x';
                 $calculated->answer = $sign
-                        .substr($answer, 0, $answerlength +1).$eX.$unit;
+                        .substr($answer, 0, $answerlength +1).$eX; // paulo.matos: bug #4901
             }
         } else {
             // Stick to plain numeric format
             $answer *= "1e$p10";
             if (0.1 <= $answer / "1e$answerlength") {
-                $calculated->answer = $sign.$answer.$unit;
+                $calculated->answer = $sign.$answer; // paulo.matos: bug #4901
             } else {
                 // Could be an idea to add some zeros here
                 $answer .= (ereg('^[0-9]*$', $answer) ? '.' : '')
                         . '00000000000000000000000000000000000000000x';
                 $oklen = $answerlength + ($p10 < 1 ? 2-$p10 : 1);
-                $calculated->answer = $sign.substr($answer, 0, $oklen).$unit;
+                $calculated->answer = $sign.substr($answer, 0, $oklen); // paulo.matos: bug #4901
             }
         }
 
@@ -797,6 +798,10 @@
         $calculated->answer = 0.0;
     }
 
+    //paulo.matos: bug #4901: extra units are added here...
+    if (!$nounits) {
+      if ($calculated->answer != 0.0) $calculated->answer .= $unit;
+    }
     /// Return the result
     return $calculated;
 }
diff -uNr moodle.orig/question/type/numerical/questiontype.php moodle/question/type/numerical/questiontype.php
--- moodle.orig/question/type/numerical/questiontype.php	2006-03-28 08:39:36.000000000 +0100
+++ moodle/question/type/numerical/questiontype.php	2006-10-05 14:39:51.000000000 +0100
@@ -249,16 +249,22 @@
     function test_response(&$question, &$state, $answer) {
         if (isset($state->responses[''])) {
             $response = $this->apply_unit(stripslashes($state->responses['']),
-             $question->options->units);
+             $question->options->units,
+             1); // paulo.matos: bug #4901
         } else {
             $response = '';
         }
 
         if (is_numeric($response) && is_numeric($answer->answer)) {
             $this->get_tolerance_interval($answer);
+
+            // paulo.matos: shouldn't this be enough? See bug #3225
+            //return ( abs($answer->answer - $response) < ($answer->tolerance + ("1.0e-".ini_get('precision')) ) );
             return ($answer->min <= $response && $answer->max >= $response);
         } else {
-            return ($response == $answer->answer);
+            // paulo.matos: we must force answer to be string, strings are
+            // converted in a weired way, e.g. "19km" == 19 (int) is true!!
+            return ($response == "$answer->answer");
         }
     }
 
@@ -384,7 +390,8 @@
     * @return float               The rawresponse with the unit taken into
     *                             account as a float.
     */
-    function apply_unit($rawresponse, $units) {
+    //paulo.matos: (bug #4901)
+    function apply_unit($rawresponse, $units, $testunits=0) {
         // Make units more useful
         $tmpunits = array();
         foreach ($units as $unit) {
@@ -401,6 +408,19 @@
             if (isset($tmpunits[$responseparts[5]])) {
                 return (float)$responseparts[1] / $tmpunits[$responseparts[5]];
             } else {
+                //paulo.matos: this way default unit is checked if exists
+                if ($testunits) {
+                   if (empty($tmpunits)) {
+                     // if no units are defined but they are present we strip nothing.
+                     return $rawresponse;
+                   } else {
+                     // however, if there are units defined and the answer has nothing
+                     // we add "something" so it isn't only numerical value check.
+                     if ($responseparts[5]=='') return $rawresponse."(no units)";
+                     return $rawresponse;
+                   }
+                }
+
                 return (float)$responseparts[1];
             }
         }
