GNOME Bugzilla – Bug 697634
complex: needless loss of precision [fixed]
Last modified: 2013-04-11 13:28:35 UTC
On 04/08/2013 12:27 PM, Morten Welinder wrote: > The proper precision to use is > l10 = gnm_log10 (FLT_RADIX); > res->output.decimal_digits = (int)gnm_ceil (GNM_MANT_DIG * l10) + > (l10 == (int)l10 ? 0 : 1); Done. This is calculated in gnm_init() and saved in an "extern int" for everybody to use. > I think should define that a NULL format given to complex_to_string > should mean that enough precision should be used to round-trip the values. I made a somewhat more involved change to complex_to_string, but the idea is the same. It always puts out enough digits to ensure precision. You can request padding to a larger field. The code to do this, and to integrate it into the rest of the app, can be found at http://www.av8n.com/gitweb/?p=gnumeric.git;a=shortlog;h=refs/heads/alpha Actually there are three patches that go together. They aren't useful separately, but they are perhaps more readable this way: -- more precise (and more readable) way to format complex numbers -- remove complex_to_string_deprecated -- make use of new formatting method I assume all interested parties know how to retrieve a patch from gitweb; if not, we can make other arrangements. Note that these numbers are not guaranteed to look pretty; they are meant to be a precise /internal/ representation. If you want pretty, split the number into real and imaginary parts, in separate cells, and format the cells. It is crucial to keep in mind the distinction between precise internal representation and readable external formatting.
I see a few problems with the complex_to_string part of this: 1. It is exposed to the user by more or less every complex function, so it cannot be simply an internal representation. In particular, users have reasonable expectations that, say, 4i gets output without a real part. There's a compatibility argument hidden here too. 2. I think you can get "-0i" or "+0i" as the imaginary part. 3. We can't have anything like gnm_decimal_width. First of all, it can't handle numbers above 1e100. Secondly, it assumes a single- character decimal separator which we cannot guarantee. (Non-C locales are another reason why numbers-in-strings was a bad idea.) Some function like g_strdup_printf or g_string_append_printf should be used so we don't have to worry about these issues.
I agree the complex_to_string part of this is messed up. Sorry about that. Part of the problem is that I mixed two topics together, mixing the precision issue with the readability issue. Both are important, and they interact, but they are not the same thing. We need to have two discussions. This is not easy, because they interact, but for now let's emphasize the distinction and worry about the interactions later. Topic 1: Let's fix the precision issue. This is germane to the topic of this bug report. It seems that gnm_decimal_digits is a possible way of fixing this. Topic 2: Let's forget about gnm_decimal_width. It was a bad idea, for multiple reasons. It is not germane to the topic of this bug report anyway. ======== If you want, I can write some code to deal with Topic 1 properly. It will be a day or so before I can start on this. ======================= As for the interaction between the two topics: Fixing the precision issue makes the readability very slightly worse, due to the extra digits. However, this is a small price to pay. The number-string crock already suffers from showing huge numbers of "insignificant digits", so anybody using such numbers must accept this, whether we fix the precision issue or not. I have some constructive ides for improving the readability, but these are off-topic for this bug report, so let's discuss them somewhere else.
I wrote the code as described in the previous comment. I did a reasonable amount of testing. The patch can be found at http://www.av8n.com/gitweb/?p=gnumeric.git;a=shortlog;h=refs/heads/alpha Look where it says "more precise way to format complex numbers" right below where it says "supporting functions". (Further down there are four patches that cancel each other out, and should be ignored.) In file complex.c there is a block of comments for complex_to_string discussing precision, formatting, and compatibility.
I fixed this with a very minimal patch. ChangeLog | 6 ++++++ NEWS | 1 + plugins/fn-complex/functions.c | 7 ++----- plugins/fn-tsa/functions.c | 5 +---- src/complex.c | 15 +++++++++++---- src/complex.h | 3 +-- 6 files changed, 22 insertions(+), 15 deletions(-) This problem has been fixed in our software repository. The fix will go into the next software release. Thank you for your bug report.