The Inbox: Kernel-nice.1213.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: Kernel-nice.1213.mcz

commits-2
Nicolas Cellier uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-nice.1213.mcz

==================== Summary ====================

Name: Kernel-nice.1213
Author: nice
Time: 8 February 2019, 11:24:45.054968 pm
UUID: d7a472c9-49dd-4b1d-b73a-13b9c7c8d4c5
Ancestors: Kernel-tonyg.1212

Provide a logarithm in base 2: log2.
This (x log2) has an additional property that (x log: 2) has not: it is exact for exact powers of 2.

While implementing LogarithmicInterval, I recently wanted to use log: 2, and this was getting as bad as in Python. See https://stackoverflow.com/questions/931995/inaccurate-logarithm-in-python/54537441#54537441

I don't know if this feature is really worth it, but whether it ends up integrated or not, at least it demonstrates how easy it is to patch Squeak.

=============== Diff against Kernel-tonyg.1212 ===============

Item was added:
+ ----- Method: Float>>log2 (in category 'mathematical functions') -----
+ log2
+ "Answer the base 2 logarithm of the receiver.
+ Arrange to answer exact result in case of exact power of 2."
+
+ ^ self significand ln / Ln2 + self exponent!

Item was added:
+ ----- Method: Fraction>>log2 (in category 'mathematical functions') -----
+ log2
+ "This function is defined because super log might overflow."
+ | res |
+ self <= 0 ifTrue: [DomainError signal: 'log2 is only defined for x > 0'].
+ "Test self < 1 before converting to float in order to avoid precision loss due to gradual underflow."
+ numerator < denominator ifTrue: [^self reciprocal log2 negated].
+ res := super log2.
+ res isFinite ifTrue: [^res].
+ ^numerator log2 - denominator log2!

Item was added:
+ ----- Method: Integer>>log2 (in category 'mathematical functions') -----
+ log2
+ self > 0 ifTrue: [^super log2].
+ ^DomainError signal: 'log2 is only defined for x > 0'!

Item was added:
+ ----- Method: LargeNegativeInteger>>log2 (in category 'mathematical functions') -----
+ log2
+ ^DomainError signal: 'log2 is only defined for x > 0'!

Item was added:
+ ----- Method: LargePositiveInteger>>log2 (in category 'mathematical functions') -----
+ log2
+ "This function is defined because super log2 might overflow."
+ | res h |
+ res := super log2.
+ res isFinite ifTrue: [^res].
+ h := self highBit.
+ ^h + (self / (1 << h)) asFloat log2!

Item was added:
+ ----- Method: Number>>log2 (in category 'mathematical functions') -----
+ log2
+ "Answer the base-2 log of the receiver."
+
+ ^self asFloat log2!

Item was changed:
  ----- Method: Number>>log: (in category 'mathematical functions') -----
  log: aNumber
  "Answer the log base aNumber of the receiver."
 
+ aNumber = 2 ifTrue: [^self log2].
  ^self ln / aNumber ln!

Item was added:
+ ----- Method: ScaledDecimal>>log2 (in category 'mathematical functions') -----
+ log2
+ "Unlike super, avoid Float overflow/underflow"
+
+ ^self asFraction log2!


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-nice.1213.mcz

Chris Muller-3
Woo hoo!   Log base 2 for LI's is something I've been wanting for a long time.

On Fri, Feb 8, 2019 at 4:25 PM <[hidden email]> wrote:

>
> Nicolas Cellier uploaded a new version of Kernel to project The Inbox:
> http://source.squeak.org/inbox/Kernel-nice.1213.mcz
>
> ==================== Summary ====================
>
> Name: Kernel-nice.1213
> Author: nice
> Time: 8 February 2019, 11:24:45.054968 pm
> UUID: d7a472c9-49dd-4b1d-b73a-13b9c7c8d4c5
> Ancestors: Kernel-tonyg.1212
>
> Provide a logarithm in base 2: log2.
> This (x log2) has an additional property that (x log: 2) has not: it is exact for exact powers of 2.
>
> While implementing LogarithmicInterval, I recently wanted to use log: 2, and this was getting as bad as in Python. See https://stackoverflow.com/questions/931995/inaccurate-logarithm-in-python/54537441#54537441
>
> I don't know if this feature is really worth it, but whether it ends up integrated or not, at least it demonstrates how easy it is to patch Squeak.
>
> =============== Diff against Kernel-tonyg.1212 ===============
>
> Item was added:
> + ----- Method: Float>>log2 (in category 'mathematical functions') -----
> + log2
> +       "Answer the base 2 logarithm of the receiver.
> +       Arrange to answer exact result in case of exact power of 2."
> +
> +       ^ self significand ln / Ln2 + self exponent!
>
> Item was added:
> + ----- Method: Fraction>>log2 (in category 'mathematical functions') -----
> + log2
> +       "This function is defined because super log might overflow."
> +       | res |
> +       self <= 0 ifTrue: [DomainError signal: 'log2 is only defined for x > 0'].
> +       "Test self < 1 before converting to float in order to avoid precision loss due to gradual underflow."
> +       numerator < denominator ifTrue: [^self reciprocal log2 negated].
> +       res := super log2.
> +       res isFinite ifTrue: [^res].
> +       ^numerator log2 - denominator log2!
>
> Item was added:
> + ----- Method: Integer>>log2 (in category 'mathematical functions') -----
> + log2
> +       self > 0 ifTrue: [^super log2].
> +       ^DomainError signal: 'log2 is only defined for x > 0'!
>
> Item was added:
> + ----- Method: LargeNegativeInteger>>log2 (in category 'mathematical functions') -----
> + log2
> +       ^DomainError signal: 'log2 is only defined for x > 0'!
>
> Item was added:
> + ----- Method: LargePositiveInteger>>log2 (in category 'mathematical functions') -----
> + log2
> +       "This function is defined because super log2 might overflow."
> +       | res h |
> +       res := super log2.
> +       res isFinite ifTrue: [^res].
> +       h := self highBit.
> +       ^h + (self / (1 << h)) asFloat log2!
>
> Item was added:
> + ----- Method: Number>>log2 (in category 'mathematical functions') -----
> + log2
> +       "Answer the base-2 log of the receiver."
> +
> +       ^self asFloat log2!
>
> Item was changed:
>   ----- Method: Number>>log: (in category 'mathematical functions') -----
>   log: aNumber
>         "Answer the log base aNumber of the receiver."
>
> +       aNumber = 2 ifTrue: [^self log2].
>         ^self ln / aNumber ln!
>
> Item was added:
> + ----- Method: ScaledDecimal>>log2 (in category 'mathematical functions') -----
> + log2
> +       "Unlike super, avoid Float overflow/underflow"
> +
> +       ^self asFraction log2!
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-nice.1213.mcz

Alistair Grant
In reply to this post by commits-2
On Fri, 8 Feb 2019 at 23:25, <[hidden email]> wrote:
>
> Provide a logarithm in base 2: log2.
> This (x log2) has an additional property that (x log: 2) has not: it is exact for exact powers of 2.
>
> While implementing LogarithmicInterval, I recently wanted to use log: 2, and this was getting as bad as in Python. See https://stackoverflow.com/questions/931995/inaccurate-logarithm-in-python/54537441#54537441

Slightly off topic... python3 has log2 :-)

$ python3
>>> from math import log2
>>> log2(2 ** 31)
31.0

Cheers,
Alistair