list:
Previously in the list someone reported a bug in float printing: st> 1e-4 0.00001 There is a bug in Float printing which I attached a patch. the variable allNines should really mean all nines except the last one, so if the last one round up, which may not be 9 itself, still can cause the whole digits round up and eat a leading zero in printing. Here is a patch to fix: diff --git a/kernel/Float.st b/kernel/Float.st index 3714f08..7e8e012 100644 --- a/kernel/Float.st +++ b/kernel/Float.st @@ -527,10 +527,11 @@ if the hardware supports it.'> allNines := true. sameDown := true. sameUp := true. + digit := 9. - [digit := num // weight. + [allNines := allNines and: [digit = 9]. + digit := num // weight. num := num \\ weight. - allNines := allNines and: [digit = 9]. sameDown := sameDown and: [num >= eps]. sameUp := sameUp and: [num < (weight - eps)]. digits := digits * 10 + digit. _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
Derek,
The issue is an underlying one in how numbers are converted to exact fractions as part of the printing process; the problem needs to be addressed there since it will be affecting more than just printing. Thomas Derek Zhou writes: > list: > > Previously in the list someone reported a bug in float printing: > > st> 1e-4 > 0.00001 > > There is a bug in Float printing which I attached a patch. the variable > allNines should really mean all nines except the last one, so if the > last one round up, which may not be 9 itself, still can cause the > whole digits round up and eat a leading zero in printing. > > Here is a patch to fix: > > diff --git a/kernel/Float.st b/kernel/Float.st > index 3714f08..7e8e012 100644 > --- a/kernel/Float.st > +++ b/kernel/Float.st > @@ -527,10 +527,11 @@ if the hardware supports it.'> > allNines := true. > sameDown := true. > sameUp := true. > + digit := 9. > > - [digit := num // weight. > + [allNines := allNines and: [digit = 9]. > + digit := num // weight. > num := num \\ weight. > - allNines := allNines and: [digit = 9]. > sameDown := sameDown and: [num >= eps]. > sameUp := sameUp and: [num < (weight - eps)]. > digits := digits * 10 + digit. > _______________________________________________ > help-smalltalk mailing list > [hidden email] > https://lists.gnu.org/mailman/listinfo/help-smalltalk _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
Thomas Worthington writes: > Derek, > The issue is an underlying one in how numbers are converted to exact fractions as part of the printing process; the problem needs to be addressed there since it will be affecting more than just printing. I don't know why printing of float has to go through exact fraction, nor why 1e-4 is converted to 13743895/137438953472 instead of 1/10000, however 13743895/137438953472 is technically correct; while printing of it is wrong. This patch fixed a bug so printing of 1e-4 through 13743895/137438953472 is correct again; which I think is a good thing. Whether we should improve converting to exact fraction or skip the convertion altogether is a seperate issue. Derek _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
In reply to this post by Derek Zhou-3
All,
The previous patch contains a bug. Please use this one: diff --git a/kernel/Float.st b/kernel/Float.st index 3714f08..c594ba6 100644 --- a/kernel/Float.st +++ b/kernel/Float.st @@ -527,10 +527,11 @@ if the hardware supports it.'> allNines := true. sameDown := true. sameUp := true. + digit := 9. - [digit := num // weight. + [allNines := allNines and: [digit = 9]. + digit := num // weight. num := num \\ weight. - allNines := allNines and: [digit = 9]. sameDown := sameDown and: [num >= eps]. sameUp := sameUp and: [num < (weight - eps)]. digits := digits * 10 + digit. @@ -555,7 +556,7 @@ if the hardware supports it.'> (num - prevWeight) abs < num ifTrue: [adjust := 1]]. digits := digits + adjust. - (adjust > 0 and: [allNines]) + (adjust = (10 - digit) and: [allNines]) ifTrue: [allNines := false. exponent := exponent + 1]. digits := digits printString. _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
Derek -
i should mention again, that contributing to gnu-smalltalk requires a formal copyright assignment - if you have not completed that process, it is best if you do not send any explicit patches - they can not be accepted; so publishing them publicly is more of a complication than a help _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
dont worry, i have assignment form filled a long time ago. also this is a simple patch, and cannot.assert copyright anyway.
On April 1, 2019 4:37:25 PM GMT+08:00, bill-auger <[hidden email]> wrote: >Derek - > >i should mention again, that contributing to gnu-smalltalk requires >a formal copyright assignment - if you have not completed that process, >it is best if you do not send any explicit patches - they can not be >accepted; so publishing them publicly is more of a complication than a >help > >_______________________________________________ >help-smalltalk mailing list >[hidden email] >https://lists.gnu.org/mailman/listinfo/help-smalltalk -- Sent from my Android device with K-9 Mail. Please excuse my brevity. _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
> On 1. Apr 2019, at 10:06, Derek Zhou <[hidden email]> wrote: > > dont worry, i have assignment form filled a long time ago. also this is a simple patch, and cannot.assert copyright anyway. Thanks for the patches! I will try to apply them this week. AFAIK unfortunately the last statement is not universally true. A series of simple patches can turn into something copyrightable. :) _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
In reply to this post by Derek Zhou-3
Derek,
It's about six months since I looked at it so I may be mis-remembering. I'll see if I can find any record of my own attempt at this bug. I do remember starting from scratch and ending up with the same algorithm which gives 13743895/137438953472 instead of 1/10000 at which point I felt I'd failed and set it aside. In what sense do you mean that 13743895/137438953472 is "technically correct"? If 13743895/137438953472 == 1/10000 then 137438953472/13743895 == 10000, which it clearly does not, so it seem to me still to be an underlying issue with asExactFraction or some related method. Thomas Derek Zhou writes: > Thomas Worthington writes: > >> Derek, >> The issue is an underlying one in how numbers are converted to exact fractions as part of the printing process; the problem needs to be addressed there since it will be affecting more than just printing. > > I don't know why printing of float has to go through exact fraction, nor > why 1e-4 is converted to 13743895/137438953472 instead of 1/10000, > however 13743895/137438953472 is technically correct; while printing of > it is wrong. This patch fixed a bug so printing of 1e-4 through > 13743895/137438953472 is correct again; which I think is a good > thing. Whether we should improve converting to exact fraction or skip > the convertion altogether is a seperate issue. > > Derek > > _______________________________________________ > help-smalltalk mailing list > [hidden email] > https://lists.gnu.org/mailman/listinfo/help-smalltalk _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
Thomas Worthington writes: > If 13743895/137438953472 == 1/10000 then 137438953472/13743895 == 10000, which it clearly does not, so it seem to me still to be an underlying issue with asExactFraction or some related method. 1e-4 is a floating point number which is not the same as 1/10000 the fraction. _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
Derek,
Are you saying that when I type 1e-4 asFraction and get 1/10000 that's wrong, then? It seems pretty obvious that if asFraction returns the right answer and asExactFraction returns the wrong answer, then there is a bug in the latter and not the former. Starting with the same input, there is no reason why they should return different answers in this particular case. It may simply be a case of asExactFraction being mis-named. The comment in the code even uses the word "approximation". More strangeness: (10 raisedTo: -4) asExactFraction 1/10000 (10 raisedTo: -4) asFloat 0.0001 1e-4 0.00001 So, I think we can firmly state that the problem here is not in the output routines. It may in fact be the input routine (i.e., the parser). Thomas Derek Zhou writes: > Thomas Worthington writes: > >> If 13743895/137438953472 == 1/10000 then 137438953472/13743895 == 10000, which it clearly does not, so it seem to me still to be an underlying issue with asExactFraction or some related method. > > 1e-4 is a floating point number which is not the same as 1/10000 the > fraction. > > _______________________________________________ > help-smalltalk mailing list > [hidden email] > https://lists.gnu.org/mailman/listinfo/help-smalltalk _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
1e-4 is a floating number by syntax. as you may know, binary floating number cannot hold the exact number of 0.0001, some kind of approximation has to be used.
if you convert a floating number to a fraction, there are 2 methods, one is asFraction, the other is asExactFraction. since the memory location of the floating number already hold the value tbat is not quite 0.0001, the computer has no way to figure out that you mean 0.0001 at the beginning because the precision was already lost. so the computer came up with a faithful fraction representation of the floating number, so you get 13743895/137438953472 on the other hand, the asFraction is supposed to be an imprecise approximation of the floating point number, you get back 1/1000 purely by luck, whatever algorithm it use, it happen to pick a fraction that you want. but generally speaking, rounding will introduce error. if you call asFloat asFraction repeatly, there is no guaranty that you get the value you oringinally had in mind. On April 18, 2019 9:40:41 PM GMT+08:00, Thomas Worthington <[hidden email]> wrote: >Derek, > Are you saying that when I type > >1e-4 asFraction > >and get > >1/10000 > >that's wrong, then? > >It seems pretty obvious that if asFraction returns the right answer and >asExactFraction returns the wrong answer, then there is a bug in the >latter and not the former. Starting with the same input, there is no >reason why they should return different answers in this particular >case. > >It may simply be a case of asExactFraction being mis-named. The comment >in the code even uses the word "approximation". > >More strangeness: > >(10 raisedTo: -4) asExactFraction >1/10000 > >(10 raisedTo: -4) asFloat >0.0001 > >1e-4 >0.00001 > > >So, I think we can firmly state that the problem here is not in the >output routines. It may in fact be the input routine (i.e., the >parser). > >Thomas > > >Derek Zhou writes: > >> Thomas Worthington writes: >> >>> If 13743895/137438953472 == 1/10000 then 137438953472/13743895 == >10000, which it clearly does not, so it seem to me still to be an >underlying issue with asExactFraction or some related method. >> >> 1e-4 is a floating point number which is not the same as 1/10000 the >> fraction. >> >> _______________________________________________ >> help-smalltalk mailing list >> [hidden email] >> https://lists.gnu.org/mailman/listinfo/help-smalltalk -- Sent from my Android device with K-9 Mail. Please excuse my brevity. _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
In reply to this post by Thomas Worthington
On April 18, 2019 9:40:41 PM GMT+08:00, Thomas Worthington <[hidden email]> wrote: >More strangeness: > >(10 raisedTo: -4) asExactFraction >1/10000 > correct; 10 raisedTo: -4 is a fraction, not a float. the asExactFraction is an noop. no rounding was involved. >(10 raisedTo: -4) asFloat >0.0001 > correct. the float value is actually not 0.0001, but something very close to it. the printing method did some further rounding and gave you the illusion that no precision was lost. >1e-4 >0.00001 > bug. which I proposed a fix previously. _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
In reply to this post by Derek Zhou-3
Derek,
You're quite right. The name and the comment on the method threw me. It's more like IEEE-754AsExactFraction which, now I look at it isn't a great name either. My apologies. Thomas Derek Zhou writes: > 1e-4 is a floating number by syntax. as you may know, binary floating number cannot hold the exact number of 0.0001, some kind of approximation has to be used. > > if you convert a floating number to a fraction, there are 2 methods, one is asFraction, the other is asExactFraction. since the memory location of the floating number already hold the value tbat is not quite 0.0001, the computer has no way to figure out that you mean 0.0001 at the beginning because the precision was already lost. so the computer came up with a faithful fraction representation of the floating number, so you get 13743895/137438953472 > > on the other hand, the asFraction is supposed to be an imprecise approximation of the floating point number, you get back 1/1000 purely by luck, whatever algorithm it use, it happen to pick a fraction that you want. but generally speaking, rounding will introduce error. if you call asFloat asFraction repeatly, there is no guaranty that you get the value you oringinally had in mind. > > On April 18, 2019 9:40:41 PM GMT+08:00, Thomas Worthington <[hidden email]> wrote: >>Derek, >> Are you saying that when I type >> >>1e-4 asFraction >> >>and get >> >>1/10000 >> >>that's wrong, then? >> >>It seems pretty obvious that if asFraction returns the right answer and >>asExactFraction returns the wrong answer, then there is a bug in the >>latter and not the former. Starting with the same input, there is no >>reason why they should return different answers in this particular >>case. >> >>It may simply be a case of asExactFraction being mis-named. The comment >>in the code even uses the word "approximation". >> >>More strangeness: >> >>(10 raisedTo: -4) asExactFraction >>1/10000 >> >>(10 raisedTo: -4) asFloat >>0.0001 >> >>1e-4 >>0.00001 >> >> >>So, I think we can firmly state that the problem here is not in the >>output routines. It may in fact be the input routine (i.e., the >>parser). >> >>Thomas >> >> >>Derek Zhou writes: >> >>> Thomas Worthington writes: >>> >>>> If 13743895/137438953472 == 1/10000 then 137438953472/13743895 == >>10000, which it clearly does not, so it seem to me still to be an >>underlying issue with asExactFraction or some related method. >>> >>> 1e-4 is a floating point number which is not the same as 1/10000 the >>> fraction. >>> >>> _______________________________________________ >>> help-smalltalk mailing list >>> [hidden email] >>> https://lists.gnu.org/mailman/listinfo/help-smalltalk _______________________________________________ help-smalltalk mailing list [hidden email] https://lists.gnu.org/mailman/listinfo/help-smalltalk |
Free forum by Nabble | Edit this page |