[Cuis-dev] Problems in class Number

Agustín Sansone agustinsansone7 at gmail.com
Mon Oct 7 19:54:12 PDT 2019


Hello!

While testing and reading the implementation of the class Number I found
some things that might be cuestionable, some errors and a method that could
have been implemented much faster:

   - In Integer, the *sumTo: anInteger *method,
   computes "self+(self+1)+...+anInteger". The problem here is that if self >
   anInteger this operation does not have sense. For this case, the
   implementation returns 0 instead of rasing an error. This kind of makes
   sense, because not adding anything could be thought as 0, nevertheless this
   is cuestionable.
   - Analogously, the *productTo: anInteger *method, computes
   self*(self+1)*...*anInteger. Similarly, in this case when self > anInteger,
   it returns 1 instead of an error. In this case, I don't think there is a
   direct correlation to think that not multiplying any number should be equal
   to 1.
   - A detail, if now we make this change in the method *productTo:
   anInteger*, there will be a small problem in the method *factorial*.
   This is because what factorial does is *"^1 productTo: self"* (after
   checking if self is not negative). So, with this new change, if we make *0
   factorial* it will raise an error, because we would be computing *"^1
   productTo: 0"*, and this would be not defined. Anyway, this can be
   easily fixed by checking this border case.
   - The *raisedToInteger: exp modulo: m *method in Integer has a very big
   problem. If we compute, for example, *"5 raisedTo: 0 modulo: 0"*, this
   returns 1. This means, that according to Smalltalk, the rest of the
   division by 0 of 1(=5^0) is equal to 1 (Yes, division by zero!!). I think
   you can see the problem. This is due the first line of the method, that
   says *"(exp = 0) ifTrue: [^ 1].", *does not check anything else. This
   problem can be easily fixed by checking if m=0 just before.
   - Now, if we compute *"1 mod: 0" *or (worse) *"(5 raisedToInteger: 0)
   mod: 0"* it raises an error informing that the division by zero is not
   defined (exactly what we could expect if we me made *"5 raisedTo: 0
   modulo: 0"*). So, not only we found an error, but also we found a
   problem of inconsistency in Smalltalk, since for the same calculation we
   can obtain two differents answers.
   - Another detail, in Number there are defined this methods: *mod:
   divisor*, *rem: divisor* y *\\ divisor*. All of this are thought like
   some kind of rest in the division. Particularly, the method *mod:
   divisor *maps to the mathematical operation of modulo of modular
   arithmetic. Smalltalk defines this operation in general for every number as
   modulo, but mathematically this operation should be only be defined for the
   natual numbers, thus it could be added some check for this. "For a
   positive integer n, two numbers a and b are said to be congruent modulo n
   ...[]" <https://en.wikipedia.org/wiki/Modular_arithmetic>
   - Last detail, if we compute *"0 raisedToInteger: 0"* this returns 1. I
   am not a math expert, but I don't think this operation should be defined if
   there is not even a consensual answer for this.
   - The *isPrime *method in Integer makes some optimization in order to
   run the algorithm in O(sqrt(self)) instead of the naive way in O(self).
   This is very intelligent, but the constant factor of this method can be
   still improved significantly. I share with you my implementation of
*isPrimeFast
   *with a small explanation. This implementation runs in general more than
   3 times faster than the actual one. I leave you a test that checks the
   correctness of it as well, and some other tests that check this complexity
   I mentioned.

Please let me know what you think.
Best regards,
Agustín Sansone
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20191007/b2c0648d/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Integer-isPrimeFast.st
Type: application/octet-stream
Size: 819 bytes
Desc: not available
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20191007/b2c0648d/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: IsPrime-Tests.st
Type: application/octet-stream
Size: 1573 bytes
Desc: not available
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20191007/b2c0648d/attachment-0001.obj>


More information about the Cuis-dev mailing list