Hi,
I found the bug during using webform with number field with small step (for input a value in milimeters). In the number.inc is part for checking of the step (step test). There is used function fmod(), but this function contains bug in PHP for low values - the result is that for example 1.1 divided by 0.1 gives modulo 2.7755575615629E-17 and not 0!
Please consider using of custom modulo function - see http://php.net/manual/en/function.fmod.php.

Comments

quicksketch’s picture

Title: Number step test modulo (fmod) error » Number step test modulo (fmod) error with odd float numbers

Thanks, a good suggestion. PHP (and computers in general) certainly need little number massaging when dealing with odd numbers and division.

sah62’s picture

I just ran into this same problem with the 7.x-3.18 release. This statement on line 565 in numbers.inc

fmod($element['#value'] - $starting_number, $element['#step']

returns 0.0099999999999999 when $element['#value'] == 3.50, $starting_number == 0, and $element['#step'] == 0.01. I expected a result of 0.

Here's a custom function that returns correct results:

function webform_fmod($n,$b) {
  return $n-$b*floor($n/$b);
}
sah62’s picture

Version: 6.x-3.17 » 7.x-4.0-alpha8
StatusFileSize
new1.96 KB

This issue still exists in 7.x-4.0-alpha8. Here's a patch.

quicksketch’s picture

Assigned: tommer » Unassigned
Status: Active » Needs review

Thanks @sah62! This needs to be applied everywhere, as it exists in all branches. Moving this to needs review to it will get picked up next time I'm going through the review queue.

sah62’s picture

Version: 7.x-4.0-alpha8 » 7.x-4.0-alpha9
quicksketch’s picture

Doh, sorry @sah62. I went through the "easy" patches the past few weeks but missed this one. Next release. :)

sah62’s picture

No prob...

quicksketch’s picture

StatusFileSize
new950 bytes

I adjusted this patch to take the advice of this poster on PHP.net. This version uses ceil() or floor() based on if the number is negative for the proper modulo value when working with negative numbers.

quicksketch’s picture

Title: Number step test modulo (fmod) error with odd float numbers » Number step test modulo (fmod) has precision errors with odd float numbers
Status: Needs review » Fixed

Committed to all branches. Thanks guys!

sah62’s picture

Works for me - thanks!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

superspring’s picture

Issue summary: View changes
Status: Closed (fixed) » Needs work

Given the webform_modulo code:
return $a - $b * (($b < 0) ? ceil($a / $b) : floor($a / $b));

If I try this with:
$a = 4.22
$b = 0.01

I get webform_modulo = 0.0099999999999998
and fmod = 0.0099999999999997

This appear to be an issue with PHP which this function does not resolve.
See var_dump(4.22-4.21);

aprogs’s picture

Hi,
I have the same issue with Webform 4 RC3.

There is a number field with next validation settings:

Minimum: 0
Maximum: 10
Step: 0.1

When I'm trying to submit a form with value 8.6 I'm getting an error:

[field-title] field value must be a multiple of 0.1. i.e. 0, 0.1, 0.2, 0.3, etc.

danchadwick’s picture

Status: Needs work » Fixed
StatusFileSize
new6.24 KB

There are two sources of this error. The first is that you can't compare floating points with the equal operator because of very small floating point rounding errors. The same routine used for fp comparisons in conditionals is used instead. The second is that due to fp rounding errors, the modulo function may return the modulus (e.g. 0.1 in the example), rather than 0. Both are explicitly tested for. To implement this I moved the fp comparison routine from conditionals.inc to number.inc.

Committed to 7.x-4.x and 8.x.

  • DanChadwick committed db57067 on 7.x-4.x
    Issue #1601968 by DanChadwick: Fixes number step modulo rounding errors.
    
  • DanChadwick committed 852cff8 on 8.x-4.x
    Issue #1601968 by DanChadwick: Fixes number step modulo rounding errors.
    

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.