| Type | Bug | Status | complete | Date | 20-Jun-2010 09:52 |
|---|---|---|---|---|---|
| Version | alpha 99 | Category | Native | Submitted by | Ladislav |
| Platform | All | Severity | crash | Priority | normal |
| Summary | EVEN?, ODD? and decimals |
|---|---|
| Description |
I consider a value to be even only if it is an integral multiple of two. This means that for some purposes 2.1 is not even. This begs a question how the EVEN? and ODD? functions shall be defined. I also noticed that the present implementation of the functions uses code with undefined behaviour (thus the severity updated to crash). |
| Example code |
>> even? 2.1 == true |
| Assigned to | n/a | Fixed in | r3 master | Last Update | 26-Jan-2015 06:13 |
|---|
| Comments | |
|---|---|
|
(0002398)
Ladislav 25-Jun-2010 08:55 |
To be even more specific, here are my alternative functions to consider:
alternative-even?: func [ number [decimal!] ] [ zero? number // 2.0 ] alternative-odd?: func [ number [decimal!] ] [ found? all [ zero? number // 1.0 not zero? number // 2.0 ] ] ; some results: >> alternative-even? 2.1 == false >> alternative-even? 2.0 == true >> alternative-odd? 2.0 == false >> alternative-odd? 2.1 == false >> alternative-odd? 1.1 == false >> alternative-odd? 1.0 == true |
|
(0002510)
Carl 21-Sep-2010 20:11 |
The problem with this definition is that decimal values, being based on floats, may contain very small computational "rounding" errors.
The current definition of ODD? and EVEN? is that if the decimal values are truncated to integer, such as when used as an index value to a series, will they be odd or even. This seems reasonable. Post a comment if you think otherwise. |
|
(0003860)
Ladislav 15-May-2013 10:50 |
Well, I understand your concern. To summarize:
* floating point arithmetic is not real arithmetic * any floating point operation (for example addition) can be described as performing the corresponding "real" operation followed by a rounding operation finding the nearest floating point number to the "real" result * that means that results of (chains of) floating point operations are in some way "approximate", differing from the "real" results even in cases when "real results" would be "integral values" like 2.0, e.g. Thus, it looks legitimate to strive for some "tolerance" - ability to tolerate "small differences from integers" in such case. However, does this implementation actually tolerate small differences from integer values? To be able to judge, I define a couple of operations allowing ULP (unit in the last place) manipulations: as-dec: func [value [integer!]] [to decimal! to binary! value] as-int: func [value [decimal!]] [to integer! to binary! value] add-ulp: func [value [decimal!] ulps [integer!]] [as-dec add as-int value ulps] Some results: >> add-ulp 2.0 0 == 2.0 >> add-ulp 2.0 1 == 2.0000000000000004 >> add-ulp 2.0 -1 == 1.9999999999999998 The results demonstrate the behaviour of the ADD-ULP function. Note that +1 and -1 ULPs are the smallest possible differences between two distinct floating point numbers. If we strive for rounding tolerance, we shall tolerate (at least) +/- 1 ULP differences. So, is the +/- 1 ULP difference tolerated by the the current EVEN? function implementation? even? 2.0 ; == true even? add-ulp 2.0 -1 ; == false Thus, we actually do not have even the smallest tolerance possible and the whole thing should be redesigned/reconsidered. |
|
(0004014)
Ladislav 26-Sep-2013 00:26 |
If wanting to ignore small (< 0.5) errors, this is the variant to consider:
alternative-even?: func [ number [decimal!] ] [ number: abs number // 2.0 case [ number < 0.5 [true] number < 1.5 [false] 'else [true] ] ] alternative-odd?: func [ number [decimal!] ] [ number: abs number // 2.0 case [ number < 0.5 [false] number < 1.5 [true] 'else [false] ] ] Note: This is the most tolerant definition possible. For example: even? 1.9999999999999998 ; == true even? 2.0 ; == true even? 2.0000000000000004 ; == true |
|
(0004017)
Ladislav 26-Sep-2013 14:15 |
EVEN? and ODD? fix working as above submitted as https://github.com/rebol/rebol/pull/151 |
| Date | User | Field | Action | Change |
|---|---|---|---|---|
| 26-Jan-2015 06:13 | abolka | Status | Modified | built => complete |
| 26-Jan-2015 06:13 | abolka | Fixedin | Modified | => r3 master |
| 11-Mar-2014 19:14 | Ladislav | Status | Modified | pending => built |
| 28-Sep-2013 06:46 | Ladislav | Description | Modified | - |
| 28-Sep-2013 06:44 | Ladislav | Description | Modified | - |
| 27-Sep-2013 09:53 | Ladislav | Description | Modified | - |
| 27-Sep-2013 09:53 | Ladislav | Description | Modified | - |
| 27-Sep-2013 09:52 | Ladislav | Description | Modified | - |
| 27-Sep-2013 09:50 | Ladislav | Status | Modified | waiting => pending |
| 27-Sep-2013 09:50 | Ladislav | Severity | Modified | minor => crash |
| 26-Sep-2013 14:16 | Ladislav | Comment : 0004017 | Modified | - |
| 26-Sep-2013 14:15 | Ladislav | Comment : 0004017 | Added | - |
| 26-Sep-2013 14:14 | Ladislav | Comment : 0004014 | Modified | - |
| 26-Sep-2013 12:04 | Ladislav | Comment : 0004014 | Modified | - |
| 26-Sep-2013 00:27 | Ladislav | Comment : 0004014 | Modified | - |
| 26-Sep-2013 00:26 | Ladislav | Comment : 0004014 | Added | - |
| 15-Aug-2013 14:29 | Ladislav | Category | Modified | Unspecified => Native |
| 18-Jun-2013 15:48 | Ladislav | Comment : 0003860 | Modified | - |
| 18-Jun-2013 15:45 | Ladislav | Comment : 0003860 | Modified | - |
| 15-May-2013 15:38 | Ladislav | Comment : 0003860 | Modified | - |
| 15-May-2013 15:35 | Ladislav | Comment : 0003860 | Modified | - |
| 15-May-2013 15:35 | Ladislav | Comment : 0003860 | Modified | - |
| 15-May-2013 10:50 | Ladislav | Comment : 0003860 | Added | - |
| 21-Sep-2010 20:12 | carl | Status | Modified | reviewed => waiting |
| 21-Sep-2010 20:11 | carl | Comment : 0002510 | Added | - |
| 21-Sep-2010 20:06 | carl | Status | Modified | submitted => reviewed |
| 25-Jun-2010 08:55 | Ladislav | Comment : 0002398 | Added | - |
| 20-Jun-2010 09:55 | Ladislav | Description | Modified | - |
| 20-Jun-2010 09:53 | Ladislav | Code | Modified | - |
| 20-Jun-2010 09:53 | Ladislav | Description | Modified | - |
| 20-Jun-2010 09:53 | Ladislav | Summary | Modified | EVEN? and decimals => EVEN?, ODD? and decimals |
| 20-Jun-2010 09:52 | Ladislav | Ticket | Added | - |