The Trunk: KernelTests-nice.404.mcz

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

The Trunk: KernelTests-nice.404.mcz

commits-2
Nicolas Cellier uploaded a new version of KernelTests to project The Trunk:
http://source.squeak.org/trunk/KernelTests-nice.404.mcz

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

Name: KernelTests-nice.404
Author: nice
Time: 7 May 2021, 9:24:51.105431 pm
UUID: 2685fbb3-2da9-4f09-8344-325b655d1c18
Ancestors: KernelTests-nice.403

Expose bugs of LargePositiveInteger sqrt as encountered in Kernel-nice.1401

1) we need twice the Float precision for deciding the case when the exact root falls between two consecutive Float (exact tie), so truncating bits too eagerly ain't gonna work

2) we need to assert that self mightBeASquare before answering an Integer. There were some cases when truncating bits would make us an exact square, and we would answer an Integer even if we are not an exact square when equipped with trailing bits !

In this testSqrtNearExactTie, we carefully craft some exact tie, and try to extract the square root of slightly bigger and smaller integers

=============== Diff against KernelTests-nice.403 ===============

Item was added:
+ ----- Method: LargePositiveIntegerTest>>assert:classAndValueEquals: (in category 'asserting') -----
+ assert: expected classAndValueEquals: actual
+ self
+ assert: expected equals: actual;
+ assert: expected class equals: actual class.!

Item was added:
+ ----- Method: LargePositiveIntegerTest>>testSqrtNearExactTie (in category 'tests - mathematical functions') -----
+ testSqrtNearExactTie
+ | p q evenTie oddTie perfectSquare inexactSquare |
+ "first construct square root results that lie exactly between 2 consecutive Float"
+ p := Float precision.
+ q := Float precision // 4.
+ evenTie := 1 << q + 1 << q + 1 << (p - q - q) + 1.
+ self assert: p + 1 = evenTie highBit.
+ self assert: evenTie asFloat significandAsInteger even. "evenTie round down to even"
+ self assert: evenTie asFloat ulp asFraction / 2 + evenTie asFloat asFraction = evenTie.
+ oddTie := 1 << q + 1 << q + 1 << (p - q - q) + 2r11.
+ self assert: p + 1 = oddTie highBit.
+ self assert: oddTie asFloat significandAsInteger even. "oddTie round up to even"
+ self assert: oddTie asFloat ulp asFraction / -2 + oddTie asFloat asFraction = oddTie.
+
+ "then assert that we can retrieve the exact root"
+ perfectSquare := evenTie squared.
+ self assert: perfectSquare sqrt classAndValueEquals: evenTie.
+
+ "now take an inexact square by excess : it falls above exact tie, and should round up"
+ inexactSquare := evenTie squared + 1.
+ self deny: inexactSquare mightBeASquare.
+ self assert: inexactSquare sqrt classAndValueEquals: evenTie asFloat successor.
+ "same with one possibly exact square so that we take both paths"
+ inexactSquare := evenTie squared + 3.
+ self assert: inexactSquare mightBeASquare.
+ self assert: inexactSquare sqrt classAndValueEquals: evenTie asFloat successor.
+ "same with less bits and a possibly exact square so that we explore yet another path"
+ inexactSquare := evenTie squared + 3 // 4.
+ self assert: inexactSquare * 4 equals: evenTie squared + 3.
+ self assert: inexactSquare mightBeASquare.
+ self assert: inexactSquare sqrt classAndValueEquals: (evenTie asFloat successor / 2).
+ "same with very very far bit to solve the tie"
+ inexactSquare := evenTie squared << 100 + 2.
+ self deny: inexactSquare mightBeASquare.
+ self assert: inexactSquare sqrt classAndValueEquals: (evenTie asFloat successor timesTwoPower: 50).
+
+ "Redo the same with odd tie, just to be sure"
+ perfectSquare := oddTie squared.
+ self assert: perfectSquare sqrt classAndValueEquals: oddTie.
+
+ "now take an inexact square by default : it falls below exact tie, and should round down"
+ inexactSquare := oddTie squared - 1.
+ self deny: inexactSquare mightBeASquare.
+ self assert: inexactSquare sqrt classAndValueEquals: oddTie asFloat predecessor.
+ "same for not possibly exact case"
+ inexactSquare := oddTie squared - 5.
+ self assert: inexactSquare mightBeASquare.
+ self assert: inexactSquare sqrt classAndValueEquals: oddTie asFloat predecessor.
+ "same with less bits"
+ inexactSquare := oddTie squared - 9 // 4.
+ self assert: inexactSquare * 4 equals: oddTie squared - 9.
+ self assert: inexactSquare mightBeASquare.
+ self assert: inexactSquare sqrt classAndValueEquals: (oddTie asFloat predecessor / 2).
+ "same with very very far bit to solve the tie"
+ inexactSquare := oddTie squared << 100 - 2.
+ self deny: inexactSquare mightBeASquare.
+ self assert: inexactSquare sqrt classAndValueEquals: (oddTie asFloat predecessor timesTwoPower: 50).!