Type | Bug | Status | complete | Date | 28-Apr-2009 09:32 |
---|---|---|---|---|---|
Version | alpha 49 | Category | Unspecified | Submitted by | Ladislav |
Platform | Linux x86 libc6 | Severity | minor | Priority | normal |
Summary | MOLD and DECIMAL-DIGITS |
---|---|
Description |
As far as I remember, the system/options/decimal-digits option was defined to make sure that if we set: system/options/decimal-digits: 17 , for any decimal number X would hold: x - load mold x == 0.0 This is no longer the case, as the example below shows. This influences the orthogonality of LOAD and MOLD and invalidates the documentation article about decimals. |
Example code |
x: 0.30000000000000004 system/options/decimal-digits: 17 same? x load mold x ; == false (should be true) |
Assigned to | n/a | Fixed in | r3 master | Last Update | 19-Sep-2013 14:35 |
---|
Comments | |
---|---|
(0000565)
BrianH 28-Apr-2009 17:29 |
The example doesn't show anything we can test. Try providing a specific number for x that has the problem you mention - the only number in the example doesn't have the problem.
In alpha 49: >> system/options/decimal-digits: 17 == 17 >> x: 5.5511151231257827e-017 == 5.5511151231257827e-017 >> x - load mold x == 0.0 |
(0000567)
Ladislav 29-Apr-2009 07:57 |
example updated, sorry for the omission |
(0000595)
BrianH 29-Apr-2009 21:02 |
Carl, I think that in his example false was supposed to be an error. I'm not sure whether 17 digits is sufficient to show the rounding error in 0.1 + 0.1 + 0.1. The error in question is unchanged between alpha 49 and 50.
In any case, the point he is making is that 0.1 + 0.1 + 0.1 has a rounding error that isn't shown by MOLD of that value, no matter what the setting for system/options/decimal-digits is. I've changed the ticket accordingly. |
(0000596)
BrianH 29-Apr-2009 21:50 |
This rounding error is a known problem with IEEE754-style binary floating point calculations, so people would expect this to be an error, and probably wouldn't want to see it.
What I think Ladislav is proposing, the system/options/decimal-digits: 17 method: >> system/options/decimal-digits: 17 >> zero? (0.1 + 0.1 + 0.1) - load mold (0.1 + 0.1 + 0.1) == true I'm not sure that this is a good idea to fix the way Ladislav is suggesting. Options like decimal-digits and binary-base can affect the behavior of REBOL functions in hidden ways. These options even existing means that you have to check them before every operation that they affect. Plus, that 17 is a magic number, and one that could change if we switched to a larger floating point representation for decimal! values. The option would have to be task-local as well. At the root of this is the idea that LOAD MOLD of a value will generate the same value. This is not the case for many values: MOLD generates approximate REBOL source, not literal representations of REBOL values. The opposite of MOLD is DO, not LOAD, and you don't necessarily get the same result even then. Literal representations of REBOL values are generated by MOLD/all, not MOLD. Aside from binding issues, in theory LOAD MOLD/all of a value should be equal to the value. If this isn't the case for a given value, this should be considered an error in MOLD/all for that datatype. If it is possible to generate values of a datatype that can't be represented in REBOL source, there needs to be a serialized syntax to represent that value that can be generated by MOLD/all (there is such an error for the word! type). Here's my suggestion, the MOLD/all method: >> zero? (0.1 + 0.1 + 0.1) - load mold (0.1 + 0.1 + 0.1) == false >> zero? (0.1 + 0.1 + 0.1) - load mold/all (0.1 + 0.1 + 0.1) == true MOLD would generate a nice representation of the value, ignoring the rounding error. Perhaps system/options/decimal-digits would affect what MOLD would consider a rounding error. MOLD/all would ignore any decimal-digits option and generate all of the digits necessary to exactly recreate the same value in memory, assuming that the decimal! is internally represented by a floating point value of the same size and format. If necessary, have it generate a serialized "#[decimal! #{hex digits}]" syntax. It's the only way to be sure. |
(0000604)
Ladislav 30-Apr-2009 10:23 |
A terminological point:
Brian uses a notion of "rounding error". This is quite unfortunate terminology, since every floating point value X exactly (i.e. without any "rounding error") represents itself. The only case when a rounding error is involved is, when a number that is not exactly representable as a floating point value is represented by a floating point value. Because of the above, for any given floating point value it is *impossible* to find out whether it "has a rounding error" or not. The same holds above: what if my goal was to obtain *exactly* the value I obtained? If that is true, then the value *does not have* any rounding error. |
(0000605)
Ladislav 30-Apr-2009 10:38 |
I am strongly *against* Brian's suggestion to have:
zero? x - load mold x == false for *every* value of system/options/decimal-digits. Why isn't it better to represent the given floating point number as precisely as requested by the user? It is provable that every 64-bit IEEE754 binary floating point number is *accurately* representable (meaning, that load mold x produces x) by a 17-digit E representation. Nevertheless, I support Brian's point with mold/all, meaning that mold/all should always (independently on system/options/decimal-digits) work so, that for every floating point value X: zero? x - load mold/all x ; == true |
(0000607)
Carl 30-Apr-2009 16:27 |
There are several issues. We can only solve these issues if we define the precise programming situations we want to support, write tests to verify those, and then modify R3 to produce those results. IFAIK, that's the only way to deal with these floating point issues.
For example, a "professional programmer" may not want R3 to do any modifications of the IEEE fp values. The programmer already knows the behavior, and will deal with it. But, a beginner (say a student) who adds a few numbers, does not want to see a crazy result (although, in some cases, it may not be prevented, this is float after all, and it is the reason we also support precision math separately.) Then, there's the rest of us, who want to get the job done, and we know that float is an "approximate value", so before we store or display it, we use ROUND to adjust for the correct result. I should also point out, that however "accurate" the string representation of the number, as the number is parsed and converted from chars to its IEEE internal format, various small "truncations" (to avoid the word "round") might occur. After all, the number does not magically get converted, we must process it using C code, with multiply and add, etc. Therefore, perhaps what BrianH has suggested is a good idea: to allow a hex mold/all representation of the number, the precise bits that are in memory. I believe that format guarantees that the stored form will recreate the precise value that was saved (molded). |
(0000608)
BrianH 30-Apr-2009 17:56 |
Ladislav, it is provable that a 64bit IEEE754 floating point number can be representable in 17 digits, true.
It is *not* provable that the (possibly future) version of REBOL that is loading the value will implement decimal! using 64bit floating point values - perhaps it will use 128bit values. Who knows? It is definitely provable most developers will not know what the 17 means either, and that the number 17 is not included when the decimal is molded. That's why I referred to the 17 as a magic number. With a hex MOLD/all representation you could statically determine that the original number was 64bit, just by its length, no questions. I had been leaning toward just doing a serialized representation when you need to, but with Carl's post above I am leaning towards doing it with every MOLD/all. |
(0000915)
Ladislav 9-Jun-2009 14:27 |
Ticket #897 added to reflect the requirement to use DECIMAL-DIGITS = 17 for MOLD/ALL |
(0000920)
BrianH 10-Jun-2009 02:11 |
As of alpha 56 system/options/decimal-digits works. A separate ticket will be created to request that this option be moved to a MOLD argument. |
(0002890)
Ladislav 18-Nov-2010 08:32 |
In the core-tests suite. |
(0003392)
Ladislav 22-Jan-2013 08:55 |
After the #1939 has been built by Carl I consider this ticket built. |
Date | User | Field | Action | Change |
---|---|---|---|---|
19-Sep-2013 14:35 | Ladislav | Status | Modified | built => complete |
22-Jan-2013 21:15 | BrianH | Fixedin | Modified | alpha 56 => r3 master |
22-Jan-2013 08:55 | Ladislav | Comment : 0003392 | Added | - |
22-Jan-2013 08:54 | Ladislav | Status | Modified | pending => built |
20-Jan-2013 18:22 | Ladislav | Comment : 0000604 | Modified | - |
20-Jan-2013 01:13 | Ladislav | Comment : 0000615 | Removed | - |
20-Jan-2013 00:00 | Ladislav | Code | Modified | - |
19-Jan-2013 23:59 | Ladislav | Comment : 0002891 | Removed | - |
19-Jan-2013 23:59 | Ladislav | Comment : 0003377 | Removed | - |
19-Jan-2013 23:47 | Ladislav | Comment : 0003377 | Added | - |
19-Jan-2013 23:43 | Ladislav | Comment : 0000605 | Modified | - |
19-Jan-2013 23:40 | Ladislav | Comment : 0000605 | Modified | - |
19-Jan-2013 23:38 | Ladislav | Comment : 0000604 | Modified | - |
19-Jan-2013 23:36 | Ladislav | Comment : 0000604 | Modified | - |
19-Jan-2013 23:35 | Ladislav | Description | Modified | - |
18-Nov-2010 08:33 | Ladislav | Comment : 0002891 | Added | - |
18-Nov-2010 08:32 | Ladislav | Comment : 0002890 | Added | - |
18-Nov-2010 08:32 | Ladislav | Platform | Modified | All => Linux x86 libc6 |
18-Nov-2010 08:32 | Ladislav | Status | Modified | tested => pending |
18-Nov-2010 08:32 | Ladislav | Category | Modified | => Unspecified |
10-Jun-2009 02:11 | BrianH | Comment : 0000920 | Added | - |
10-Jun-2009 02:08 | BrianH | Status | Modified | reviewed => tested |
10-Jun-2009 02:08 | BrianH | Fixedin | Modified | => alpha 56 |
9-Jun-2009 14:27 | Ladislav | Comment : 0000915 | Added | - |
3-May-2009 10:40 | Ladislav | Comment : 0000615 | Added | - |
30-Apr-2009 18:08 | BrianH | Comment : 0000608 | Modified | - |
30-Apr-2009 17:56 | BrianH | Comment : 0000608 | Added | - |
30-Apr-2009 16:27 | carl | Comment : 0000607 | Added | - |
30-Apr-2009 10:38 | Ladislav | Comment : 0000605 | Added | - |
30-Apr-2009 10:23 | Ladislav | Comment : 0000604 | Added | - |
30-Apr-2009 00:28 | BrianH | Code | Modified | - |
30-Apr-2009 00:26 | BrianH | Code | Modified | - |
29-Apr-2009 21:50 | BrianH | Comment : 0000596 | Added | - |
29-Apr-2009 21:23 | BrianH | Comment : 0000595 | Modified | - |
29-Apr-2009 21:11 | BrianH | Status | Modified | built => reviewed |
29-Apr-2009 21:11 | BrianH | Fixedin | Modified | alpha 50 => none |
29-Apr-2009 21:11 | BrianH | Code | Modified | - |
29-Apr-2009 21:02 | BrianH | Comment : 0000595 | Added | - |
29-Apr-2009 15:59 | carl | Status | Modified | submitted => built |
29-Apr-2009 15:59 | carl | Fixedin | Modified | => alpha 50 |
29-Apr-2009 13:26 | Ladislav | Status | Modified | problem => submitted |
29-Apr-2009 07:58 | Ladislav | Code | Modified | - |
29-Apr-2009 07:58 | Ladislav | Code | Modified | - |
29-Apr-2009 07:57 | Ladislav | Comment : 0000567 | Added | - |
29-Apr-2009 07:55 | Ladislav | Comment : 0000566 | Removed | - |
29-Apr-2009 07:53 | Ladislav | Comment : 0000566 | Added | - |
28-Apr-2009 17:30 | BrianH | Status | Modified | submitted => problem |
28-Apr-2009 17:29 | BrianH | Status | Modified | problem => submitted |
28-Apr-2009 17:29 | BrianH | Comment : 0000565 | Added | - |
28-Apr-2009 17:26 | BrianH | Status | Modified | submitted => problem |
28-Apr-2009 17:26 | BrianH | Code | Modified | - |
28-Apr-2009 17:26 | BrianH | Description | Modified | - |
28-Apr-2009 09:32 | Ladislav | Ticket | Added | - |