Hello,
I am trying to write a method called "inWords" for Number class to write a number in words. For example: 15 inWords should output: fifteen I wrote a code, it works for every 2 digit number except 19, for which it outputs "tennine". I guess there is a logic error in algorithm but I cannot find it. Anyone has an idea? Here is the code: Number extend [ inWords [ | clone part_1 part_2 part_3 | part_1 := ''. part_2 := ''. part_3 := ''. clone := self copy. ((clone \\ 100) = 0) ifTrue: [ part_1 := ''. part_2 := ''. ]. ((clone \\ 100) < 20 and: [(clone \\ 100) > 10]) ifTrue: [ ((clone \\ 100) = 11) ifTrue: [ part_2 := 'eleven'. ]. ((clone \\ 100) = 12) ifTrue: [ part_2 := 'twelve'. ]. ((clone \\ 100) = 13) ifTrue: [ part_2 := 'thirteen'. ]. ((clone \\ 100) = 14) ifTrue: [ part_2 := 'fourteen'. ]. ((clone \\ 100) = 15) ifTrue: [ part_2 := 'fifteen'. ]. ((clone \\ 100) = 16) ifTrue: [ part_2 := 'sixteen'. ]. ((clone \\ 100) = 17) ifTrue: [ part_2 := 'seventeen'. ]. ((clone \\ 100) = 18) ifTrue: [ part_2 := 'eighteen'. ]. ((clone \\ 100) = 19) ifTrue: [ part_2 := 'nineteen'. ]. ] ifFalse: [ ((clone \\ 10) = 0) ifTrue: [ part_1 := ''. ]. ((clone \\ 10) = 1) ifTrue: [ part_1 := 'one'. ]. ((clone \\ 10) = 2) ifTrue: [ part_1 := 'two'. ]. ((clone \\ 10) = 3) ifTrue: [ part_1 := 'three'. ]. ((clone \\ 10) = 4) ifTrue: [ part_1 := 'four'. ]. ((clone \\ 10) = 5) ifTrue: [ part_1 := 'five'. ]. ((clone \\ 10) = 6) ifTrue: [ part_1 := 'six'. ]. ((clone \\ 10) = 7) ifTrue: [ part_1 := 'seven'. ]. ((clone \\ 10) = 8) ifTrue: [ part_1 := 'eight'. ]. ((clone \\ 10) = 9) ifTrue: [ part_1 := 'nine'. ]. clone := clone - (clone \\ 10). ((clone \\ 100) = 10) ifTrue: [ part_2 := 'ten'. ]. ((clone \\ 100) = 20) ifTrue: [ part_2 := 'twenty'. ]. ((clone \\ 100) = 30) ifTrue: [ part_2 := 'thirty'. ]. ((clone \\ 100) = 40) ifTrue: [ part_2 := 'forty'. ]. ((clone \\ 100) = 50) ifTrue: [ part_2 := 'fifty'. ]. ((clone \\ 100) = 60) ifTrue: [ part_2 := 'sixty'. ]. ((clone \\ 100) = 70) ifTrue: [ part_2 := 'seventy'. ]. ((clone \\ 100) = 80) ifTrue: [ part_2 := 'eighty'. ]. ((clone \\ 100) = 90) ifTrue: [ part_2 := 'ninety'. ]. ]. ^part_2, part_1 ] ] Transcript show: (19 inWords) _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk
Canol Gökel
|
Something is going on while interpreting the ifTrue:ifFalse: not sure why... Paolo should be able to tell you what's going on. In the mean time, you could try the following : Number extend [ inWords [ | part_1 part_2 part_3 | part_1 := ''. part_2 := ''. part_3 := ''. ((self \\ 100) < 20 and: [(self \\ 100) > 10]) ifTrue: [ part_2 := {'eleven'. 'twelve' . 'thirteen'. 'fourteen'. 'fifteen'. 'sixteen'. 'seventeen'. 'eighteen'. 'nineteen'} at: ((self \\ 100) - 10) . ] ifFalse: [ part_1 := {''. 'one'. 'two'. 'three'. 'four'. 'five'. 'six'. 'seven'. 'eight'. 'nine'} at: ((self \\ 10) + 1). part_2 := {'' . 'ten'. 'twenty'. 'thirty'. 'forty'. 'fifty'. 'sixty'. 'seventy'. 'eighty'. 'ninety'. 'hundred'} at: ((self // 10) + 1). ]. ^part_2, part_1 ] ] (1 to: 99) do: [:i | Transcript show: i inWords; nl] Regards, Olivier Le samedi 05 juillet 2008 à 17:15 +0000, Canol Gokel a écrit : > Hello, > > I am trying to write a method called "inWords" for Number class to write a > number in words. For example: > > 15 inWords > > should output: > > fifteen > > I wrote a code, it works for every 2 digit number except 19, for which it > outputs "tennine". I guess there is a logic error in algorithm but I cannot find > it. Anyone has an idea? Here is the code: > > Number extend [ > inWords [ > | clone part_1 part_2 part_3 | > > part_1 := ''. > part_2 := ''. > part_3 := ''. > > clone := self copy. > > ((clone \\ 100) = 0) ifTrue: [ > part_1 := ''. > part_2 := ''. > ]. > ((clone \\ 100) < 20 and: [(clone \\ 100) > 10]) ifTrue: [ > ((clone \\ 100) = 11) ifTrue: [ > part_2 := 'eleven'. > ]. > ((clone \\ 100) = 12) ifTrue: [ > part_2 := 'twelve'. > ]. > ((clone \\ 100) = 13) ifTrue: [ > part_2 := 'thirteen'. > ]. > ((clone \\ 100) = 14) ifTrue: [ > part_2 := 'fourteen'. > ]. > ((clone \\ 100) = 15) ifTrue: [ > part_2 := 'fifteen'. > ]. > ((clone \\ 100) = 16) ifTrue: [ > part_2 := 'sixteen'. > ]. > ((clone \\ 100) = 17) ifTrue: [ > part_2 := 'seventeen'. > ]. > ((clone \\ 100) = 18) ifTrue: [ > part_2 := 'eighteen'. > ]. > ((clone \\ 100) = 19) ifTrue: [ > part_2 := 'nineteen'. > ]. > ] ifFalse: [ > ((clone \\ 10) = 0) ifTrue: [ > part_1 := ''. > ]. > ((clone \\ 10) = 1) ifTrue: [ > part_1 := 'one'. > ]. > ((clone \\ 10) = 2) ifTrue: [ > part_1 := 'two'. > ]. > ((clone \\ 10) = 3) ifTrue: [ > part_1 := 'three'. > ]. > ((clone \\ 10) = 4) ifTrue: [ > part_1 := 'four'. > ]. > ((clone \\ 10) = 5) ifTrue: [ > part_1 := 'five'. > ]. > ((clone \\ 10) = 6) ifTrue: [ > part_1 := 'six'. > ]. > ((clone \\ 10) = 7) ifTrue: [ > part_1 := 'seven'. > ]. > ((clone \\ 10) = 8) ifTrue: [ > part_1 := 'eight'. > ]. > ((clone \\ 10) = 9) ifTrue: [ > part_1 := 'nine'. > ]. > > clone := clone - (clone \\ 10). > > ((clone \\ 100) = 10) ifTrue: [ > part_2 := 'ten'. > ]. > ((clone \\ 100) = 20) ifTrue: [ > part_2 := 'twenty'. > ]. > ((clone \\ 100) = 30) ifTrue: [ > part_2 := 'thirty'. > ]. > ((clone \\ 100) = 40) ifTrue: [ > part_2 := 'forty'. > ]. > ((clone \\ 100) = 50) ifTrue: [ > part_2 := 'fifty'. > ]. > ((clone \\ 100) = 60) ifTrue: [ > part_2 := 'sixty'. > ]. > ((clone \\ 100) = 70) ifTrue: [ > part_2 := 'seventy'. > ]. > ((clone \\ 100) = 80) ifTrue: [ > part_2 := 'eighty'. > ]. > ((clone \\ 100) = 90) ifTrue: [ > part_2 := 'ninety'. > ]. > ]. > > ^part_2, part_1 > ] > ] > > Transcript show: (19 inWords) > > > > _______________________________________________ > help-smalltalk mailing list > [hidden email] > http://lists.gnu.org/mailman/listinfo/help-smalltalk > _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
olivier blanc <olivier.blanc <at> laposte.net> writes:
> > Something is going on while interpreting the ifTrue:ifFalse: not sure > why... Yes, it executes the ifFalse: part when it comes to 19 but I don't know why... > In the mean time, you could try the following : > > Regards, > > Olivier Thank you very much, your code is working! _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk
Canol Gökel
|
In reply to this post by ZuLuuuuuu
Canol Gokel wrote:
> Hello, > > I am trying to write a method called "inWords" for Number class to write a > number in words. For example: > > 15 inWords > > should output: > > fifteen > > I wrote a code, it works for every 2 digit number except 19, for which it > outputs "tennine". I guess there is a logic error in algorithm but I cannot find > it. No, it's my bug. I'm sorry. :-( Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Hi Paolo,
I couldn't find a way to point out where the bug is appearing. How do you trace it down ? Olivier Le jeudi 10 juillet 2008 à 15:22 +0200, Paolo Bonzini a écrit : > Canol Gokel wrote: > > Hello, > > > > I am trying to write a method called "inWords" for Number class to write a > > number in words. For example: > > > > 15 inWords > > > > should output: > > > > fifteen > > > > I wrote a code, it works for every 2 digit number except 19, for which it > > outputs "tennine". I guess there is a logic error in algorithm but I cannot find > > it. > > No, it's my bug. I'm sorry. :-( > > Paolo > > > _______________________________________________ > help-smalltalk mailing list > [hidden email] > http://lists.gnu.org/mailman/listinfo/help-smalltalk _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Olivier Blanc wrote:
> Hi Paolo, > > I couldn't find a way to point out where the bug is appearing. > How do you trace it down ? I modified a little the code (just to make it more similar to my Smalltalk coding style), and got a "stack height mismatch", which hints to a bug in the compiler. Alternatively, you can use -E to do an execution trace (I didn't try that, but it should point to something very weird). Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Paolo Bonzini wrote:
> Olivier Blanc wrote: >> Hi Paolo, >> >> I couldn't find a way to point out where the bug is appearing. >> How do you trace it down ? > > I modified a little the code (just to make it more similar to my > Smalltalk coding style), and got a "stack height mismatch", which hints > to a bug in the compiler. In the bytecode optimizer, more precisely. The optimization of jumps-to-jumps was causing a jump with a small range (<256 bytes) to become a jump with a large range (>256 bytes), and the optimizer was truncating the jump. I fixed this in 43baff3b8586cae9cb505e8d3bc43c7915d4aa28 by more or less rewriting the bytecode optimizer (_gst_optimize_bytecodes). Then I noticed a speedup opportunity, because the optimizer was not generating a few bytecodes that are in the bytecode set. These are "compound" bytecodes such as this one 101 = bytecode bc101 { PREFETCH (); DUP_STACK_TOP (); POP_JUMP_FALSE (arg); } (used in compiling #and: and #or: messages), this one 165 = bytecode bc165 { PREFETCH (); NOT_NIL_SPECIAL (); POP_JUMP_FALSE (arg); } (resulting from "a notNil ifTrue: [...]"), and this one 134 = bytecode bc134 { ADVANCE (); POP_STACK_TOP (); JUMP_BACK (arg); } (used in compiling #whileTrue: and #whileFalse: messages). Generation of these bytecodes is now done, after these three commits: - 9bc2bf594fd75b4bbc02f4a13b421f545d507880 (a bug fix in the printing of CompiledMethods) - 18c63d0a2fcb677f176c30dd933366172f81a328 (bugs in the implementation of the bytecodes that went unnoticed until now) - 5aa9ebc511af8bd0615d3fb9e10198d145c22098 (actual generation of the bytecodes in the optimizer) I applied all four patches to the 3.0 branch too. Should there be problems, on the branch I might revert the last one or two. Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Free forum by Nabble | Edit this page |