Skip to content

Commit

Permalink
Merge pull request #317 from buildingSMART/78-testcase-floating-point…
Browse files Browse the repository at this point in the history
…-numbers-tolerance

78 testcase floating point numbers tolerance
  • Loading branch information
atomczak authored Jun 10, 2024
2 parents 906935c + e9525b6 commit 7171c00
Show file tree
Hide file tree
Showing 66 changed files with 96 additions and 35 deletions.
64 changes: 32 additions & 32 deletions Documentation/testcases/scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2672,7 +2672,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''100000.''

### Comparison tolerance for floating point one lower bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_one_lower_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_one_lower_bound.ids
Comparison tolerance for floating point one lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2681,7 +2681,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''1.''

### Comparison tolerance for floating point one lower bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_one_lower_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_one_lower_bound.ids
Comparison tolerance for floating point one lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2690,7 +2690,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''1.''

### Comparison tolerance for floating point one upper bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_one_upper_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_one_upper_bound.ids
Comparison tolerance for floating point one upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2699,7 +2699,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''1.''

### Comparison tolerance for floating point one upper bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_one_upper_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_one_upper_bound.ids
Comparison tolerance for floating point one upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2708,7 +2708,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''1.''

### Comparison tolerance for floating point positive low number lower bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_positive_low_number_lower_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_positive_low_number_lower_bound.ids
Comparison tolerance for floating point positive low number lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2717,7 +2717,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''0.0000001''

### Comparison tolerance for floating point positive low number lower bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_positive_low_number_lower_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_positive_low_number_lower_bound.ids
Comparison tolerance for floating point positive low number lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2726,7 +2726,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''0.0000001''

### Comparison tolerance for floating point positive low number upper bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_positive_low_number_upper_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_positive_low_number_upper_bound.ids
Comparison tolerance for floating point positive low number upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2735,7 +2735,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''0.0000001''

### Comparison tolerance for floating point positive low number upper bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_positive_low_number_upper_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_positive_low_number_upper_bound.ids
Comparison tolerance for floating point positive low number upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2744,7 +2744,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''0.0000001''

### Comparison tolerance for floating point zero lower bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_zero_lower_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_zero_lower_bound.ids
Comparison tolerance for floating point zero lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2753,7 +2753,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''0.''

### Comparison tolerance for floating point zero lower bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_zero_lower_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_zero_lower_bound.ids
Comparison tolerance for floating point zero lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2762,7 +2762,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''0.''

### Comparison tolerance for floating point zero upper bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_zero_upper_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_zero_upper_bound.ids
Comparison tolerance for floating point zero upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2771,7 +2771,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''0.''

### Comparison tolerance for floating point zero upper bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_zero_upper_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_zero_upper_bound.ids
Comparison tolerance for floating point zero upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2780,7 +2780,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''0.''

### Comparison tolerance for floating point negative low number lower bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_negative_low_number_lower_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_negative_low_number_lower_bound.ids
Comparison tolerance for floating point negative low number lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2789,7 +2789,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-0.0000001''

### Comparison tolerance for floating point negative low number lower bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_negative_low_number_lower_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_negative_low_number_lower_bound.ids
Comparison tolerance for floating point negative low number lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2798,7 +2798,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-0.0000001''

### Comparison tolerance for floating point negative low number upper bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_negative_low_number_upper_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_negative_low_number_upper_bound.ids
Comparison tolerance for floating point negative low number upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2807,7 +2807,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-0.0000001''

### Comparison tolerance for floating point negative low number upper bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_negative_low_number_upper_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_negative_low_number_upper_bound.ids
Comparison tolerance for floating point negative low number upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2816,7 +2816,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-0.0000001''

### Comparison tolerance for floating point negative one lower bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_negative_one_lower_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_negative_one_lower_bound.ids
Comparison tolerance for floating point negative one lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2825,7 +2825,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-1.''

### Comparison tolerance for floating point negative one lower bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_negative_one_lower_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_negative_one_lower_bound.ids
Comparison tolerance for floating point negative one lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2834,7 +2834,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-1.''

### Comparison tolerance for floating point negative one upper bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_negative_one_upper_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_negative_one_upper_bound.ids
Comparison tolerance for floating point negative one upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2843,7 +2843,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-1.''

### Comparison tolerance for floating point negative one upper bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_negative_one_upper_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_negative_one_upper_bound.ids
Comparison tolerance for floating point negative one upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2852,7 +2852,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-1.''

### Comparison tolerance for floating point negative high number lower bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_negative_high_number_lower_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_negative_high_number_lower_bound.ids
Comparison tolerance for floating point negative high number lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2861,7 +2861,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-1000000.''

### Comparison tolerance for floating point negative high number lower bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_negative_high_number_lower_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_negative_high_number_lower_bound.ids
Comparison tolerance for floating point negative high number lower bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2870,7 +2870,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-1000000.''

### Comparison tolerance for floating point negative high number upper bound

``` ids tolerance/pass_comparison_tolerance_for_floating_point_negative_high_number_upper_bound.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_negative_high_number_upper_bound.ids
Comparison tolerance for floating point negative high number upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2879,7 +2879,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-1000000.''

### Comparison tolerance for floating point negative high number upper bound

``` ids tolerance/fail_comparison_tolerance_for_floating_point_negative_high_number_upper_bound.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_negative_high_number_upper_bound.ids
Comparison tolerance for floating point negative high number upper bound
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2888,7 +2888,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,''-1000000.''

### Comparison tolerance for floating point range greater than zero exclusive

``` ids tolerance/fail_comparison_tolerance_for_floating_point_range_greater_than_zero_exclusive.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_range_greater_than_zero_exclusive.ids
Comparison tolerance for floating point range greater than zero exclusive
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2897,7 +2897,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,xs:double MinExclusive(''0.'')

### Comparison tolerance for floating point range greater than zero exclusive

``` ids tolerance/pass_comparison_tolerance_for_floating_point_range_greater_than_zero_exclusive.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_range_greater_than_zero_exclusive.ids
Comparison tolerance for floating point range greater than zero exclusive
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2906,7 +2906,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,xs:double MinExclusive(''0.'')

### Comparison tolerance for floating point range greater than zero inclusive

``` ids tolerance/fail_comparison_tolerance_for_floating_point_range_greater_than_zero_inclusive.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_range_greater_than_zero_inclusive.ids
Comparison tolerance for floating point range greater than zero inclusive
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2915,7 +2915,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,xs:double MinInclusive(''0.'')

### Comparison tolerance for floating point range greater than zero inclusive

``` ids tolerance/pass_comparison_tolerance_for_floating_point_range_greater_than_zero_inclusive.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_range_greater_than_zero_inclusive.ids
Comparison tolerance for floating point range greater than zero inclusive
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2924,7 +2924,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,xs:double MinInclusive(''0.'')

### Comparison tolerance for floating point range lower than zero exclusive

``` ids tolerance/fail_comparison_tolerance_for_floating_point_range_lower_than_zero_exclusive.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_range_lower_than_zero_exclusive.ids
Comparison tolerance for floating point range lower than zero exclusive
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2933,7 +2933,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,xs:double MaxExclusive(''0.'')

### Comparison tolerance for floating point range lower than zero exclusive

``` ids tolerance/pass_comparison_tolerance_for_floating_point_range_lower_than_zero_exclusive.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_range_lower_than_zero_exclusive.ids
Comparison tolerance for floating point range lower than zero exclusive
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2942,7 +2942,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,xs:double MaxExclusive(''0.'')

### Comparison tolerance for floating point range lower than zero inclusive

``` ids tolerance/fail_comparison_tolerance_for_floating_point_range_lower_than_zero_inclusive.ids
``` ids tolerance/fail-comparison_tolerance_for_floating_point_range_lower_than_zero_inclusive.ids
Comparison tolerance for floating point range lower than zero inclusive
Entity: ''IFCWALL''
Requirements:
Expand All @@ -2951,7 +2951,7 @@ Property: ''Foo_Bar'',''Foo'',IFCREAL,xs:double MaxInclusive(''0.'')

### Comparison tolerance for floating point range lower than zero inclusive

``` ids tolerance/pass_comparison_tolerance_for_floating_point_range_lower_than_zero_inclusive.ids
``` ids tolerance/pass-comparison_tolerance_for_floating_point_range_lower_than_zero_inclusive.ids
Comparison tolerance for floating point range lower than zero inclusive
Entity: ''IFCWALL''
Requirements:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ DATA;
#7=IFCWALL('2nJrDaLQfJ1QPhdJR0o97J',$,$,$,$,$,$,$,$);
#8=IFCPROPERTYSET('16MocU_IDOF8_x3Iqllz0d',$,'Foo_Bar',$,(#10));
#9=IFCRELDEFINESBYPROPERTIES('1xdwj8qGXK4hzoNbvMdXJW',$,$,$,(#7),#8);
#10=IFCPROPERTYSINGLEVALUE('Foo',$,IFCREAL(-1000001.00000100001),$);
#10=IFCPROPERTYSINGLEVALUE('Foo',$,IFCREAL(-1000001.0000011),$);
ENDSEC;
END-ISO-10303-21;
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ DATA;
#7=IFCWALL('2nJrDaLQfJ1QPhdJR0o97J',$,$,$,$,$,$,$,$);
#8=IFCPROPERTYSET('16MocU_IDOF8_x3Iqllz0d',$,'Foo_Bar',$,(#10));
#9=IFCRELDEFINESBYPROPERTIES('1xdwj8qGXK4hzoNbvMdXJW',$,$,$,(#7),#8);
#10=IFCPROPERTYSINGLEVALUE('Foo',$,IFCREAL(0.000001),$);
#10=IFCPROPERTYSINGLEVALUE('Foo',$,IFCREAL(0.0000011),$);
ENDSEC;
END-ISO-10303-21;
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ DATA;
#7=IFCWALL('2nJrDaLQfJ1QPhdJR0o97J',$,$,$,$,$,$,$,$);
#8=IFCPROPERTYSET('16MocU_IDOF8_x3Iqllz0d',$,'Foo_Bar',$,(#10));
#9=IFCRELDEFINESBYPROPERTIES('1xdwj8qGXK4hzoNbvMdXJW',$,$,$,(#7),#8);
#10=IFCPROPERTYSINGLEVALUE('Foo',$,IFCREAL(-0.000001),$);
#10=IFCPROPERTYSINGLEVALUE('Foo',$,IFCREAL(-0.0000011),$);
ENDSEC;
END-ISO-10303-21;
61 changes: 61 additions & 0 deletions Documentation/tolerance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Tolerance value in IDS

## Equality tolerance

Because of rounding errors, a tolerance value must always be considered for the equality of floating-point numbers (doubles in ids:simpleValue and xs:restriction).

To support both low numbers, like an area of a wire expressed in square meters, and high numbers, like a length of a railway, the IDS uses both a relative and a fixed component, following the formula:

`x == v ⇒ (v - abs(v) × ϵ - ϵ) < x < (v + abs(v) × ϵ + ϵ)`
with a tolerance value being: `ϵ = 1.0e⁻⁶`

The table below demonstrates characteristic ranges of values within the tolerance:

|v|lower bound<br>`(v - abs(v) × ε - ε)`| upper bound<br>`(v + abs(v) × ε + ε)`| absolute delta|
|---:|-------------:|-------------:|--:|
| 100000.0 | 99999.899999 | 100000.100001 | 0.200002 |
| 10000.0 | 9999.989999 | 10000.010001 | 0.020002 |
| 1000.0 | 999.998999 | 1000.001001 | 0.002002 |
| 100.0 | 99.999899 | 100.000101 | 0.000202 |
| 10.0 | 9.999989 | 10.000011 | 2.2E-05 |
| 1.0 | 0.999998 | 1.000002 | 4E-06 |
| 0.1 | 0.0999989 | 0.1000011 | 2.2E-06 |
| 0.01 | 0.00999899 | 0.01000101 | 2.02E-06 |
| 0.001 | 0.000998999 | 0.001001001 | 2.002E-06 |
| 0.0001 | 0.0000989999 | 0.0001010001 | 2.0002E-06 |
| 0.00001 | 0.00000899999 | 0.00001100001 | 2.00002E-06 |
| 0.000001 | -0.000000000001 | 0.000002000001 | 2.000002E-06 |
| 0.0000001 | -0.0000009000001 | 0.0000011000001 | 2.0000002E-06 |
| 0 | -0.000001 | 0.000001 | 2.0E-06 |
| -0.0000001 | -0.0000011000001 | 0.0000009000001 | 2.0000002E-06 |
| -0.000001 | -0.0000020000 | 0.000000000001 | 2.000002E-06 |
| -0.00001 | -0.0000110000 | -0.00000899999 | 2.00002E-06 |
| -0.0001 | -0.0001010001 | -0.0000989999 | 2.0002E-06 |
| -0.001 | -0.0010010010 | -0.000998999 | 2.002E-06 |
| -0.01 | -0.0100010100 | -0.00999899 | 2.02E-06 |
| -0.1 | -0.1000011000 | -0.0999989 | 2.2E-06 |
| -1.0 | -1.0000020000 | -0.999998 | 4E-06 |
| -10.0 | -10.0000110000 | -9.999989 | 2.2E-05 |
| -100.0 | -100.0001010000 | -99.999899 | 0.000202 |
| -1000.0 | -1000.0010010000 | -999.998999 | 0.002002 |
| -10000.0 | -10000.0100010000 | -9999.989999 | 0.020002 |
| -100000.0 | -100000.1000010000 | -99999.899999 | 0.200002 |
| -1000000.0 | -1000001.0000010000 * | -999998.999999 | 2.000002 |

\* If the least significant digits are beyond the precision of a IEEE74 double (approximately 17 digits), it might result in a false positive. For example, -1000001.00000100001 would still pass as being equal to -1000000.0, even though being below the lower bound.

Note: the tolerance value is not configurable, as it is specific only for rounding errors, not for construction-related tolerances, for which users need to provide an explicit range.

## Range tolerance

Adding tolerance to range checks would open up all kinds of strange edge cases like 41.999958 being both in the range 42-50 inclusive, but also < 42 exclusive. For that reason, **exclusive ranges should be shrunk, while inclusive ranges should be stretched**.

For example:
- `x > 0 ⇒ x > 1.0e⁻⁶`
- `x >= 0 ⇒ x >= -1.0e⁻⁶`

If a numeric range constraint's spread is lower than the agreed limit, the Audit-tool should raise a warning.

#

Note: the history of these agreements can be traced in the history of [issue 78](https://github.com/buildingSMART/IDS/issues/78), [issue 36](https://github.com/buildingSMART/IDS/issues/36), and in [the summary by @giuseppeverduciALMA](https://github.com/buildingSMART/IDS/blob/0d50fd8f2dbd5b388f6fafb67da255cc3ce2b4ca/Documentation/tolerance.md).

0 comments on commit 7171c00

Please sign in to comment.