Moodle

Incorrect use of tolerance in numerical questions

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Critical Critical
  • Resolution: Fixed
  • Affects Version/s: 2.0
  • Fix Version/s: None
  • Component/s: Quiz
  • Labels:
    None
  • Environment:
    All
  • Affected Branches:
    MOODLE_20_STABLE

Description

In a question where the correct answer is 2.238 +- 0.002 the answer 2.24 should be marked correct but is not. 2.2399999 is however.

Activity

Hide
Martin Dougiamas added a comment -

From Julian Sedding (jps502 at york.ac.uk) Friday, 13 May 2005, 08:15 PM:

This is a problem with the internal number representation I noticed before, but the fix slipped through somewhere. Fix will come together with some other changes in numerical.

From Julian Sedding (jps502 at york.ac.uk) Sunday, 15 May 2005, 01:08 AM:

Fixed.

From Paulo Matos (paulo.matos at fct.unl.pt) Monday, 27 March 2006, 10:43 PM:

I'm using this version:

Id: questiontype.php,v 1.14.2.4 2005/09/25 21:03:12 mindforge Exp

And I hit the bug!! I look at the quick hack of adding a very

small fraction, however it did not work always!

As stated on:

http://www.php.net/manual/en/language.types.float.php

Floats should NEVER NEVER be compared by equality!!!

If you have the tolerance (proper value for each tolerance

type), why don't you do:

abs($answer->answer - $response) < ($tolerance+$tinyfraction)

and instead calculate the interval and then compare:

$answer->min <= $response && $answer->max >= $response

I found this problem by a simple response of

15.8

+- 0.1 (tolerance)

Regards,

Paulo

From Gustav Delius (gwd2 at york.ac.uk) Tuesday, 28 March 2006, 12:37 AM:

Hi Paulo,

the trick with the tiny number is in fact what the questiontype is using. However apparently the number that was chosen, 0.00000000000000001 was too small. I have now increased it to 0.0000000000001.

Thanks for the report.

From Paulo Matos (paulo.matos at fct.unl.pt) Tuesday, 28 March 2006, 02:00 AM:

I just discovered that 'precision' setting on /etc/php.ini,

is somehow related to this. If you set the tiny fraction to

1.0e-(precision) it will work!

From Paulo Matos (paulo.matos at fct.unl.pt) Tuesday, 28 March 2006, 06:41 AM:

My test case, I changed the line:

return ($answer->min <= $response && $answer->max >= $response);

to:

return ( abs($answer->answer - $response) < ($answer->tolerance + (1.0e-.ini_get('precision')) ) );

and this works!

I assume that the same change get_tolerance_interval() would

produce the same changes.

However I would suggest that you use the inequality form instead

of the interval form, this way the (float) problem won't be

masquerade. So get_tolerance (_interval) would return the correct

value of tolerance used on the inequality.

MDL-4901 will hit this area code, just leving here the link.

Regards,

Paulo Matos

From Gustav Delius (gwd2 at york.ac.uk) Tuesday, 28 March 2006, 03:42 PM:

Paulo, I like that use of ini_get('precision'). I have put it into CVS HEAD already. Thanks.

I haven't made the other changes you suggested just because they are not as important, but feel free to use your code when you write your own question types, which I really hope you will.

Show
Martin Dougiamas added a comment - From Julian Sedding (jps502 at york.ac.uk) Friday, 13 May 2005, 08:15 PM: This is a problem with the internal number representation I noticed before, but the fix slipped through somewhere. Fix will come together with some other changes in numerical. From Julian Sedding (jps502 at york.ac.uk) Sunday, 15 May 2005, 01:08 AM: Fixed. From Paulo Matos (paulo.matos at fct.unl.pt) Monday, 27 March 2006, 10:43 PM: I'm using this version: Id: questiontype.php,v 1.14.2.4 2005/09/25 21:03:12 mindforge Exp And I hit the bug!! I look at the quick hack of adding a very small fraction, however it did not work always! As stated on: http://www.php.net/manual/en/language.types.float.php Floats should NEVER NEVER be compared by equality!!! If you have the tolerance (proper value for each tolerance type), why don't you do: abs($answer->answer - $response) < ($tolerance+$tinyfraction) and instead calculate the interval and then compare: $answer->min <= $response && $answer->max >= $response I found this problem by a simple response of 15.8 +- 0.1 (tolerance) Regards, Paulo From Gustav Delius (gwd2 at york.ac.uk) Tuesday, 28 March 2006, 12:37 AM: Hi Paulo, the trick with the tiny number is in fact what the questiontype is using. However apparently the number that was chosen, 0.00000000000000001 was too small. I have now increased it to 0.0000000000001. Thanks for the report. From Paulo Matos (paulo.matos at fct.unl.pt) Tuesday, 28 March 2006, 02:00 AM: I just discovered that 'precision' setting on /etc/php.ini, is somehow related to this. If you set the tiny fraction to 1.0e-(precision) it will work! From Paulo Matos (paulo.matos at fct.unl.pt) Tuesday, 28 March 2006, 06:41 AM: My test case, I changed the line: return ($answer->min <= $response && $answer->max >= $response); to: return ( abs($answer->answer - $response) < ($answer->tolerance + (1.0e-.ini_get('precision')) ) ); and this works! I assume that the same change get_tolerance_interval() would produce the same changes. However I would suggest that you use the inequality form instead of the interval form, this way the (float) problem won't be masquerade. So get_tolerance (_interval) would return the correct value of tolerance used on the inequality. MDL-4901 will hit this area code, just leving here the link. Regards, Paulo Matos From Gustav Delius (gwd2 at york.ac.uk) Tuesday, 28 March 2006, 03:42 PM: Paulo, I like that use of ini_get('precision'). I have put it into CVS HEAD already. Thanks. I haven't made the other changes you suggested just because they are not as important, but feel free to use your code when you write your own question types, which I really hope you will.
Hide
Michael Blake added a comment -

assign to a valid user

Show
Michael Blake added a comment - assign to a valid user
Hide
Tim Hunt added a comment -

In reponse to:

> From Paulo Matos (paulo.matos at fct.unl.pt) Tuesday, 28 March 2006, 06:41 AM:
> My test case, I changed the line:
> return ($answer->min <= $response && $answer->max >= $response);
> to:
> return ( abs($answer->answer - $response) < ($answer->tolerance + (1.0e-.ini_get('precision')) ) );

this is not right, because the get_tolerance_interval() method can, at least in theory, do more complicated things.

Show
Tim Hunt added a comment - In reponse to: > From Paulo Matos (paulo.matos at fct.unl.pt) Tuesday, 28 March 2006, 06:41 AM: > My test case, I changed the line: > return ($answer->min <= $response && $answer->max >= $response); > to: > return ( abs($answer->answer - $response) < ($answer->tolerance + (1.0e-.ini_get('precision')) ) ); this is not right, because the get_tolerance_interval() method can, at least in theory, do more complicated things.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: