Nicolas Cellier uploaded a new version of KernelTests to project The Trunk: http://source.squeak.org/trunk/KernelTests-nice.421.mcz
==================== Summary ====================
Name: KernelTests-nice.421 Author: nice Time: 26 April 2022, 11:09:45.55052 am UUID: cadcb57f-5e1f-8247-be4c-5b1235c3b821 Ancestors: KernelTests-nice.420
Where we show that divideSecureBy: is not robust to some extreme test case.
For example this choice of scaling: s := anObject real abs + anObject imaginary abs. might create an overflow - just choose Float fmax for both divisor real and imaginary.
If we simply replace with: s := anObject real abs max: anObject imaginary abs. then a second test case shows another potential problem in the computation of result real/imaginary parts: newReal := ars*brs + (ais*bis) / s. The intermediate ars*brs + (ais*bis) does overflow, while pre-dividing each term with s would not.
=============== Diff against KernelTests-nice.420 ===============
Item was added: + ----- Method: ComplexTest>>testSecureDivisionDoesNotOverflow (in category 'tests') ----- + testSecureDivisionDoesNotOverflow + + | c1 c2 scale | + "Note: this test used to fail with legacy version of divideSecureBy:" + c1 := (2 + 1i). + c2 := (1 + 1i). + scale := Float fmax. + self testSecureDivisionOf: c1 by: c2 scaledBy: scale. + "And this one fails with incomplete correction of above method" + c1 := (1/2 + 1i) / (5 << 48). + c2 := (1 + 1i). + scale := Float fminDenormalized. + self testSecureDivisionOf: c1 by: c2 scaledBy: scale!
Item was added: + ----- Method: ComplexTest>>testSecureDivisionOf:by:scaledBy: (in category 'tests') ----- + testSecureDivisionOf: c1 by: c2 scaledBy: scale + "Note: this test used to fail with legacy version of divideSecureBy:" + + | quo expected | + quo := c1 / c2. + expected := quo real / scale + (quo imaginary / scale) i. + "check in precondition that the scaled division c1/(c2*scale) would not oevrflow" + self assert: expected real isFinite. + self assert: expected imaginary isFinite. + "now retry with scaling" + quo := c1 divideSecureBy: (c2 * scale). + self assert: quo real isFinite. + self assert: quo imaginary isFinite. + self assert: (expected real - quo real) abs / (expected real ulp) < 3. + self assert: (expected imaginary - quo imaginary) abs / (expected imaginary ulp) < 3.!
packages@lists.squeakfoundation.org