Aw: Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric).
hello @all, hello @Morten, hello @John Denker, i've tried to code two functions 'bin_range' and 'dec_range' to provide the functionality i'm looking for, and would be happy if someone experienced can take the time and have a look on it. i started an 'issue' for it in 'https://gitlab.gnome.org/GNOME/gnumeric/-/issues/591', there you find the code and a testsheet. weaknesses i'm aware of but can't solve without help are: respecting 'long doubles', corner cases which need handling by defined limits or specific variables, tia, best regards, b. ___ gnumeric-list mailing list gnumeric-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnumeric-list
Re: Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric).
> i'd like to learn how rounding for display is done, some of it might be > useful for improvements i'm thinking about. string-to-value is, basically, the C library's strtod. ("Basically" because there are complications like decimal comma, thousands separators, and probably other such things.) value-to-string is in goffice/math/go-dtoa.c and is based on musl's printf code. It's changed to handle things like decimal comma. As far as I know, both ways have full accuracy in the round-to-nearest sense under two conditions: (1) a sane C library -- glibc is fine, and (2) ieee-854 semantics of double and long double -- x86 is fine. M. ___ gnumeric-list mailing list gnumeric-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnumeric-list
Re: Aw: Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric).
1) Here are a couple of famous scholarly articles somewhat relevant to our current discussion: William D Clinger "How to Read Floating Point Numbers Accurately" https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.45.4152=rep1=pdf Guy L Steele and Jon L White "How to Print Floating-Point Numbers Accurately" https://lists.nongnu.org/archive/html/gcl-devel/2012-10/pdfkieTlklRzN.pdf 2) I dug up an old example of a simple, obvious algorithm that fails miserably at a somewhat-related task, namely normalizing a longitude so that it falls in the half-open interval [-180, 180). It fails due to inevitable floating-point rounding errors. Also included is a simple (slightly less obvious) algorithm that performs much better. The self-compiling C++ source is here: https://www.av8n.com/cgit/FPU/plain/pv180.c?id=67067c555e1d1e281a008d440e189db709ec3ec3 ___ gnumeric-list mailing list gnumeric-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnumeric-list
Aw: Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric).
hello @all, hello @Morten, Morten pointed out: > "There are two types of rounding in Gnumeric: the rounding functions such as ROUND. These change the values. Then there is the rounding implied by attaching a format to a cell. That does not change the value, only its display:" theese roundings partly produce different results, e.g. 0,24983 is displayed (16 decimals) as 0,2498 but "=round(0,24983;16)" produces 0,2499 (see red marked cells in attached sheet). i'd like to learn how rounding for display is done, some of it might be useful for improvements i'm thinking about. thus i'd like to know where it is in the code, can anybody help with a pointer? - and i'd still like to know which routine doe's 'input parsing' and converting it into values - tia, best regards, b. --- Gesendet: Donnerstag, 08. Juli 2021 um 00:16 Uhr Von: "Morten Welinder" An: "Steven D'Aprano" Cc: "Gnumeric Mailing List" Betreff: Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric). Gnumeric's rounding here is indeed done with round_to_int(x * 10^d) / 10^d except that round_to_int deliberately misrounds 0.5-1ulp to 1. That's not important here. differences_between_round_and_display.gnumeric Description: application/gnumeric ___ gnumeric-list mailing list gnumeric-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnumeric-list
deco-math_step_00_b_sa_code_exact_rounddown_roundup_in_gnumeric | was: Aw: Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric).
hello Morten, acc. to a proposal of John Denker to work around wrong floor() results for 'zombie values' by floor(x) < x ? floor(x) : floor(x) - 1; i'd try to put it into goffice/goffice/math/go-math.c, and it seems to work. would you mind to check the code: --- double go_fake_trunc (double x) { x = go_d2d (x); if (x == floor (x)) return x; // edit b. wip 2021-07-09: trying to avoid wrong results for rounddown return (x >= 0) // ori was: ? floor (go_add_epsilon (x)) ? floor ( x ) <= x ? floor( x ) : floor( x ) - 1 // ori was: : -floor (go_add_epsilon (-x)); : -floor ( -x ) >= -x ? -floor( -x ) : -floor ( -x ) - 1; } --- if this (or a variant, i'm not! an experienced coder and open for all improving suggestions) is ok i'd like to help to implement similar for the other affected functions. attached a sheet with the results patched / standard for a value i tested with. best regards, b. --- Gesendet: Donnerstag, 08. Juli 2021 um 00:16 Uhr Von: "Morten Welinder" An: "Steven D'Aprano" Cc: "Gnumeric Mailing List" Betreff: Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric). Gnumeric's rounding here is indeed done with round_to_int(x * 10^d) / 10^d except that round_to_int deliberately misrounds 0.5-1ulp to 1. That's not important here. This means that, in general, you should not expect last-bit accuracy for this operation. Both the multiplication and the division can introduce rounding errors. I am willing to entertain patches that fix that if (a) someone is sufficiently interested to do the work, and (b) can do it in a sane way that doesn't involve making strings out of numbers. This is not a beginner's task. But note that the function implemented would be x -> round_to_base2(round_to_base10(x,d),53). In other words, you are inherently double rounding. Allow me to point out that while well-defined, it is not a very sane thing to do, except in the cases where the outer round is known to be a no-op. There are two types of rounding in Gnumeric: the rounding functions such as ROUND. These change the values. Then there is the rounding implied by attaching a format to a cell. That does not change the value, only its display: even if you format A1 to show two decimals, then another cell containing =A1*42 will still see the full precision of A1. Morten ___ gnumeric-list mailing list gnumeric-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnumeric-list deco-math_step_00_b_sa_code_exact_rounddown_roundup_in_gnumeric.ods Description: application/vnd.oasis.opendocument.spreadsheet ___ gnumeric-list mailing list gnumeric-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnumeric-list
Aw: Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric).
hello @ Steven, > Do you know for a fact that Gnumeric implements its rounding by multiplying 0,344 * 1E16 or are you guessing? from functions.c / gnumeric_round: gnm_float number = value_get_as_float (argv[0]); gnm_float digits = argv[1] ? value_get_as_float (argv[1]) : 0; if (digits >= 0) { if (digits <= GNM_MAX_EXP) { gnm_float p10 = gnm_pow10 ((int)digits); number = gnm_fake_round (number * p10) / p10; ... > Gnumeric *does* have access to the digit 4 in the 17th decimal place, because Gnumeric correctly prints it when you set the cell formatting to 17 decimal places. yes, but that's string conversion which is slow afaik, too slow to use it in calculations, > In context, you made a comment that when rounding the value (quote) "it only adapt's the display, but doesn't change the value" which is incorrect. Rounding changes the value. that was said to a statement of you that gnumeric already rounds the value correctly for display. i pointed out that that rounding for display is 'display only'. best regards and thanks for keeping up ... b. --- Gesendet: Mittwoch, 07. Juli 2021 um 23:41 Uhr Von: "Steven D'Aprano" An: gnumeric-list@gnome.org Betreff: Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric). On Wed, Jul 07, 2021 at 06:01:26PM +0200, newbie nullzwei wrote: > regarding the 4 being rounded up ... the standard rounding process in > gnumeric has no access to the digit '4', instead in the process of > rounding to 16 digits the '4' in 17th place becomes powered up to a ',5' > ('=0,344 * 1E16' -> 3000,5) and with rounding > 'ties away from zero' as usual in spreadsheets this rounds up. Do you know for a fact that Gnumeric implements its rounding by multiplying 0,344 * 1E16 or are you guessing? If that is in fact what Gnumeric does, that would explain why its rounding is buggy. That's not a safe way to implement rounding unless you are very, very careful, and clearly the implementation is not careful enough :-( Gnumeric *does* have access to the digit 4 in the 17th decimal place, because Gnumeric correctly prints it when you set the cell formatting to 17 decimal places. > in rounding with IEEE proposal (standard) 'ties to even' this won't > happen, thus one of the next steps i'm going to propose is to implement an > additional rounding mode and to use that for 'correction rounding' of > slightly deviating addition results. that might end the > 0,30004 story. In this specific case, *if* Gnumeric implements rounding in the way you suggest, then simply changing the internal rounding mode back to the default IEEE-754 rules will fix the issue for *this* case. But I have no confidence that it is working in other cases. > > That is incorrect, it changes the value. > > key '0,30004' in a cell, key '= {that cell} - 0,3' in another > cell, change the display length of the first cell and watch the result in > the second cell staying unchanged ... the value is not changed, what is > displayed to you as 0,3 is 0,30004 in the background. Of course, if all you do is change the cell format, all you do is change the way the value is displayed. That is not in question. I understand that cell formatting only changes the display. In context, you made a comment that when rounding the value (quote) "it only adapt's the display, but doesn't change the value" which is incorrect. Rounding changes the value. -- Steve ___ gnumeric-list mailing list gnumeric-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnumeric-list ___ gnumeric-list mailing list gnumeric-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnumeric-list
Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric).
On Wed, Jul 07, 2021 at 06:16:46PM -0400, Morten Welinder wrote: > Gnumeric's rounding here is indeed done with > > round_to_int(x * 10^d) / 10^d > > except that round_to_int deliberately misrounds 0.5-1ulp to 1. That's > not important here. Thank you Morten for introducing some reality into this discussion. It's good to have confirmation that this is what Gnumeric is doing. -- Steve ___ gnumeric-list mailing list gnumeric-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnumeric-list
Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric).
Gnumeric's rounding here is indeed done with round_to_int(x * 10^d) / 10^d except that round_to_int deliberately misrounds 0.5-1ulp to 1. That's not important here. This means that, in general, you should not expect last-bit accuracy for this operation. Both the multiplication and the division can introduce rounding errors. I am willing to entertain patches that fix that if (a) someone is sufficiently interested to do the work, and (b) can do it in a sane way that doesn't involve making strings out of numbers. This is not a beginner's task. But note that the function implemented would be x -> round_to_base2(round_to_base10(x,d),53). In other words, you are inherently double rounding. Allow me to point out that while well-defined, it is not a very sane thing to do, except in the cases where the outer round is known to be a no-op. There are two types of rounding in Gnumeric: the rounding functions such as ROUND. These change the values. Then there is the rounding implied by attaching a format to a cell. That does not change the value, only its display: even if you format A1 to show two decimals, then another cell containing =A1*42 will still see the full precision of A1. Morten ___ gnumeric-list mailing list gnumeric-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnumeric-list
Re: Re: Re: Re: deco-Math project, step 00_a: exact bin and dec 'ranges' (in gnumeric).
On Wed, Jul 07, 2021 at 06:01:26PM +0200, newbie nullzwei wrote: >regarding the 4 being rounded up ... the standard rounding process in >gnumeric has no access to the digit '4', instead in the process of >rounding to 16 digits the '4' in 17th place becomes powered up to a ',5' >('=0,344 * 1E16' -> 3000,5) and with rounding >'ties away from zero' as usual in spreadsheets this rounds up. Do you know for a fact that Gnumeric implements its rounding by multiplying 0,344 * 1E16 or are you guessing? If that is in fact what Gnumeric does, that would explain why its rounding is buggy. That's not a safe way to implement rounding unless you are very, very careful, and clearly the implementation is not careful enough :-( Gnumeric *does* have access to the digit 4 in the 17th decimal place, because Gnumeric correctly prints it when you set the cell formatting to 17 decimal places. >in rounding with IEEE proposal (standard) 'ties to even' this won't >happen, thus one of the next steps i'm going to propose is to implement an >additional rounding mode and to use that for 'correction rounding' of >slightly deviating addition results. that might end the >0,30004 story. In this specific case, *if* Gnumeric implements rounding in the way you suggest, then simply changing the internal rounding mode back to the default IEEE-754 rules will fix the issue for *this* case. But I have no confidence that it is working in other cases. >> That is incorrect, it changes the value. > >key '0,30004' in a cell, key '= {that cell} - 0,3' in another >cell, change the display length of the first cell and watch the result in >the second cell staying unchanged ... the value is not changed, what is >displayed to you as 0,3 is 0,30004 in the background. Of course, if all you do is change the cell format, all you do is change the way the value is displayed. That is not in question. I understand that cell formatting only changes the display. In context, you made a comment that when rounding the value (quote) "it only adapt's the display, but doesn't change the value" which is incorrect. Rounding changes the value. -- Steve ___ gnumeric-list mailing list gnumeric-list@gnome.org https://mail.gnome.org/mailman/listinfo/gnumeric-list