"{ Encoding: utf8 }"
"{ Package: 'stx:goodies/regression' }"
"{ NameSpace: RegressionTests }"
TestCase subclass:#LargeFloatTest
instanceVariableNames:''
classVariableNames:''
poolDictionaries:''
category:'tests-Regression-Numbers'
!
!LargeFloatTest methodsFor:'helpers'!
actualPrecisionOf:aFloatClass
"get the actual number of valid bits in the mantissa.
This does a real test (i.e. does not believe the compiled-in ifdefs)"
|one half x count|
one := aFloatClass unity. "/ 1.0 in this class
"/ largefloats have infinite precition (potentially)
one precision isFinite ifFalse:[^ Infinity positive].
half := one coerce:0.5.
x := one.
count := 0.
[ one + x ~= one] whileTrue:[
x := x * half.
count := count + 1.
].
^ count
"
self basicNew actualPrecisionOf:ShortFloat
self basicNew actualPrecisionOf:Float
self basicNew actualPrecisionOf:LongFloat
"
"Modified: / 10-10-2017 / 12:50:21 / cg"
! !
!LargeFloatTest methodsFor:'tests'!
test01_Nan
"NaN in all avaliable formats."
|shouldBeNaN|
shouldBeNaN := 0.0 asLargeFloat uncheckedDivide: 0.0.
self assert:( shouldBeNaN isMemberOf:LargeFloat ).
self assert:( shouldBeNaN isNaN ).
self assert:( shouldBeNaN isFinite not ).
shouldBeNaN := 0.0 asLargeFloat uncheckedDivide: 0.0.
self assert:( shouldBeNaN asShortFloat isNaN ).
self assert:( shouldBeNaN asLongFloat isNaN ).
self should:[ shouldBeNaN asInteger ] raise:DomainError.
self assert:( shouldBeNaN + 1 ) isNaN.
self assert:( shouldBeNaN + 1.0 ) isNaN.
self assert:( shouldBeNaN + 1.0 asShortFloat ) isNaN.
self assert:( shouldBeNaN + 1.0 asLongFloat ) isNaN.
self assert:( shouldBeNaN + 1.0 asLargeFloat ) isNaN.
self assert:( 1 + shouldBeNaN ) isNaN.
self assert:( 1.0 + shouldBeNaN ) isNaN.
self assert:( 1.0 asShortFloat + shouldBeNaN ) isNaN.
self assert:( 1.0 asLongFloat + shouldBeNaN ) isNaN.
self assert:( 1.0 asLargeFloat + shouldBeNaN ) isNaN.
self assert:( shouldBeNaN - 1 ) isNaN.
self assert:( shouldBeNaN - 1.0 ) isNaN.
self assert:( shouldBeNaN - 1.0 asShortFloat ) isNaN.
self assert:( shouldBeNaN - 1.0 asLongFloat ) isNaN.
self assert:( shouldBeNaN - 1.0 asLargeFloat ) isNaN.
self assert:( 1 - shouldBeNaN ) isNaN.
self assert:( 1.0 - shouldBeNaN ) isNaN.
self assert:( 1.0 asShortFloat - shouldBeNaN ) isNaN.
self assert:( 1.0 asLongFloat - shouldBeNaN ) isNaN.
self assert:( 1.0 asLargeFloat - shouldBeNaN ) isNaN.
"
self basicNew test01_Nan
"
!
test02_Inf
"Infinity in all avaliable formats."
|check posInf negInf|
check :=
[:v1 :v2 |
posInf := v1 uncheckedDivide: v2.
self assert:( posInf isMemberOf:v1 class ).
self assert:( posInf isNaN not ).
self assert:( posInf isFinite not ).
self assert:( posInf isInfinite ).
self assert:( posInf positive ).
self assert:( posInf negative not ).
self assert:( posInf isNegativeInfinity not).
self assert:( posInf isPositiveInfinity ).
negInf := v1 negated uncheckedDivide: v2.
self assert:( negInf isMemberOf:v1 class ).
self assert:( negInf isNaN not ).
self assert:( negInf isFinite not ).
self assert:( negInf isInfinite ).
self assert:( negInf positive not).
self assert:( negInf negative ).
self assert:( negInf isNegativeInfinity ).
self assert:( negInf isPositiveInfinity not ).
self assert:( negInf + negInf = negInf).
self assert:( posInf + posInf = posInf).
self assert:( negInf + posInf) isNaN.
self assert:( posInf + negInf) isNaN.
self assert:( negInf - posInf = negInf).
self assert:( negInf - negInf) isNaN.
self assert:( posInf - negInf = posInf).
self assert:( posInf - posInf) isNaN.
self assert:( posInf + v1) = posInf.
self assert:( posInf - v1) = posInf.
self assert:( negInf + v1) = negInf.
self assert:( negInf - v1) = negInf.
].
check value: 1.0 asLargeFloat value: 0.0 asLargeFloat.
"
self basicNew test02_Inf
"
!
test03_Conversion
self assert:( 1.0 asLargeFloat asTrueFraction == 1 ).
self assert:( 2.0 asLargeFloat asTrueFraction == 2 ).
self assert:( 4.0 asLargeFloat asTrueFraction == 4 ).
self assert:( 8.0 asLargeFloat asTrueFraction == 8 ).
self assert:( 16.0 asLargeFloat asTrueFraction == 16 ).
self assert:( 1048576.0 asLargeFloat asTrueFraction == 1048576 ).
self assert:( 0.5 asLargeFloat asTrueFraction = (1/2) ).
self assert:( 0.25 asLargeFloat asTrueFraction = (1/4) ).
self assert:( 0.125 asLargeFloat asTrueFraction = (1/8) ).
"
self basicNew test03_Conversion
"
"Modified: / 10-10-2017 / 15:27:24 / cg"
!
test04_Arithmetic
self assert:( 1.0 asLargeFloat + 1.0 ) class == LargeFloat.
self assert:( 1.0 asLargeFloat + 1.0 asShortFloat ) class == LargeFloat.
self assert:( 1.0 asLargeFloat + 1.0 asFloat ) class == LargeFloat.
self assert:( 1.0 asLargeFloat + 1 ) class == LargeFloat.
self assert:( 1.0 asLargeFloat - 1.0 ) class == LargeFloat.
self assert:( 1.0 asLargeFloat - 1.0 asShortFloat ) class == LargeFloat.
self assert:( 1.0 asLargeFloat - 1.0 asFloat ) class == LargeFloat.
self assert:( 1.0 asLargeFloat - 1 ) class == LargeFloat.
self assert:( 1.0 asLargeFloat * 1.0 ) class == LargeFloat.
self assert:( 1.0 asLargeFloat * 1.0 asShortFloat ) class == LargeFloat.
self assert:( 1.0 asLargeFloat * 1.0 asFloat ) class == LargeFloat.
self assert:( 1.0 asLargeFloat * 1 ) class == LargeFloat.
self assert:( 1.0 asLargeFloat / 1.0 ) class == LargeFloat.
self assert:( 1.0 asLargeFloat / 1.0 asShortFloat ) class == LargeFloat.
self assert:( 1.0 asLargeFloat / 1.0 asFloat ) class == LargeFloat.
self assert:( 1.0 asLargeFloat / 1 ) class == LargeFloat.
self assert:( 1.0 asLargeFloat + 1.0 asLargeFloat) = 2.0 asLargeFloat.
self assert:( 1.0 asLargeFloat + 0.0 asLargeFloat) = 1.0 asLargeFloat.
self assert:( 1.0 asLargeFloat + 2.0 asLargeFloat) = 3.0 asLargeFloat.
self assert:( 1.0 asLargeFloat + 3.0 asLargeFloat) = 4.0 asLargeFloat.
self assert:( 1.0 asLargeFloat + 1.0 asLargeFloat negated) = 0.0 asLargeFloat.
self assert:( 1.0 asLargeFloat + 2.0 asLargeFloat negated) = -1.0 asLargeFloat.
self assert:( 1.0 asLargeFloat + -1.0 asLargeFloat negated) = 2.0 asLargeFloat.
self assert:( 1.0 asLargeFloat - 1.0 asLargeFloat) = 0.0 asLargeFloat.
self assert:( 1.0 asLargeFloat - 0.0 asLargeFloat) = 1.0 asLargeFloat.
self assert:( 1.0 asLargeFloat - 2.0 asLargeFloat) = -1.0 asLargeFloat.
self assert:( 1.0 asLargeFloat - 3.0 asLargeFloat) = -2.0 asLargeFloat.
self assert:( 1.0 asLargeFloat - 1.0 asLargeFloat negated) = 2.0 asLargeFloat.
self assert:( 1.0 asLargeFloat - 2.0 asLargeFloat negated) = 3.0 asLargeFloat.
self assert:( 1.0 asLargeFloat - -1.0 asLargeFloat negated) = 0.0 asLargeFloat.
self assert:( 1.0 asLargeFloat * 1.0 asLargeFloat) = 1.0 asLargeFloat.
self assert:( 1.0 asLargeFloat * 0.0 asLargeFloat) = 0.0 asLargeFloat.
self assert:( 1.0 asLargeFloat * 2.0 asLargeFloat) = 2.0 asLargeFloat.
self assert:( 1.0 asLargeFloat * 3.0 asLargeFloat) = 3.0 asLargeFloat.
self assert:( 2.0 asLargeFloat * 3.0 asLargeFloat) = 6.0 asLargeFloat.
self assert:( 1.0 asLargeFloat * 1.0 asLargeFloat negated) = -1.0 asLargeFloat.
self assert:( 1.0 asLargeFloat * 2.0 asLargeFloat negated) = -2.0 asLargeFloat.
self assert:( 1.0 asLargeFloat * -1.0 asLargeFloat negated) = 1.0 asLargeFloat.
self assert:( 1.0 asLargeFloat / 1.0 asLargeFloat) = 1.0 asLargeFloat.
self assert:( 1.0 asLargeFloat / 2.0 asLargeFloat) = 0.5 asLargeFloat.
self assert:( 3.0 asLargeFloat / 2.0 asLargeFloat) = (3/2) asLargeFloat.
"
self basicNew test04_Arithmetic
"
!
test04b_Division
|epsilon|
"/ self assert:( 1.0 asLargeFloat / 1.0 ) class == LargeFloat.
"/ self assert:( 1.0 asLargeFloat / 1.0 asShortFloat ) class == LargeFloat.
"/ self assert:( 1.0 asLargeFloat / 1.0 asFloat ) class == LargeFloat.
"/ self assert:( 1.0 asLargeFloat / 1 ) class == LargeFloat.
"/
"/ self assert:( 1.0 asLargeFloat / 1.0 asLargeFloat) = 1.0 asLargeFloat.
"/ self assert:( 1.0 asLargeFloat / 2.0 asLargeFloat) = 0.5 asLargeFloat.
"/ self assert:( 3.0 asLargeFloat / 2.0 asLargeFloat) = (3/2) asLargeFloat.
self assert:( 0.25 asLargeFloat / 2.0 asLargeFloat) = 0.125 asLargeFloat.
self assert:( 1.0 asLargeFloat / 2.0 asLargeFloat) = 0.5 asLargeFloat.
self assert:( 1.0 asLargeFloat / 4.0 asLargeFloat) = 0.25 asLargeFloat.
self assert:( 1.0 asLargeFloat / 8.0 asLargeFloat) = 0.125 asLargeFloat.
"/ the precision of a largeInteger is the precision of its origin
epsilon := 1.0 asLargeFloat epsilon.
self assert:(( 1.0 asLargeFloat / 5.0 asLargeFloat) isAlmostEqualTo:0.2 withError:epsilon).
self assert:(( 1.0 asLargeFloat / 10.0 asLargeFloat) isAlmostEqualTo:0.1 withError:epsilon).
"/ the precision of a largeInteger is the precision of its origin
epsilon := 1.0 / (2 raisedTo:(LargeFloat defaultPrecision - 1)).
epsilon := 0.00000000000000001. "/ -- fails
epsilon := 0.0000000000000001.
self assert:(( 1 asLargeFloat / 5 asLargeFloat) isAlmostEqualTo:0.2 withError:epsilon).
self assert:(( 1 asLargeFloat / 10 asLargeFloat) isAlmostEqualTo:0.1 withError:epsilon).
"
self basicNew test04b_Division
"
"Created: / 10-10-2017 / 15:13:28 / cg"
!
test04c_Multiplication
self assert:((1 asLargeFloat to:50 asLargeFloat) product) = (50 factorial)
"
self basicNew test04c_Multiplication
"
"Created: / 10-10-2017 / 16:22:56 / cg"
!
test05_Comparing
|compiledMethod|
self assert:( 2.0 asLargeFloat = 2 ).
self assert:( 2.0 asLargeFloat = 2.0 asShortFloat ).
self assert:( 2.0 asLargeFloat = 2.0 ).
self assert:( 2.0 asLargeFloat = 2.0 asLongFloat ).
self assert:( 2.0 asLargeFloat = 2.0 asLargeFloat ).
self assert:( 2.0 asLargeFloat = 3 ) not.
self assert:( 2.0 asLargeFloat = 3.0 asShortFloat ) not.
self assert:( 2.0 asLargeFloat = 3.0 ) not.
self assert:( 2.0 asLargeFloat = 3.0 asLongFloat ) not.
self assert:( 2.0 asLargeFloat = 3.0 asLargeFloat ) not.
self assert:( 2.0 asLargeFloat < 3 ).
self assert:( 2.0 asLargeFloat < 3.0 asShortFloat ).
self assert:( 2.0 asLargeFloat < 3.0 asLargeFloat ).
"/ test fails when stc code, jit code works
compiledMethod := self class compiledMethodAt:#'test05_Comparing'.
(compiledMethod notNil
and:[compiledMethod byteCode isNil]) ifTrue:[
"/ stc-compiled code handles not slightly differently
"/ listed compares will fail
'LargeFloatTest >> test05_Comparing test with 200000000000000000000 or similiar are skipped due would fail when stc code' infoPrintCR.
] ifFalse:[
self assert:( 200000000000000000000.0 asLargeFloat < 200000000000100000000 ).
self assert:( 200000000000000000000 < 200001000000000000000.0 asLargeFloat ).
self assert:( 200000000000000000000.0 asLargeFloat <= 200000000000000000001 ).
self assert:( 200000000000000000000.0 asLargeFloat <= 200000000000000000000 ).
self assert:( 200000000000000000000 <= 200001000000000000000.0 asLargeFloat ).
self assert:( 200000000000000000000 <= 200000000000000000000.0 asLargeFloat ).
].
self assert:( 2.0 asLargeFloat <= 3 ).
self assert:( 2.0 asLargeFloat <= 2 ).
self assert:( 2.0 asLargeFloat <= 3.0 asShortFloat ).
self assert:( 2.0 asLargeFloat <= 2.0 asShortFloat ).
self assert:( 2.0 asLargeFloat <= 3.0 asLongFloat ).
self assert:( 2.0 asLargeFloat <= 2.0 asLongFloat ).
self assert:( 2.0 asLargeFloat <= 3.0 asLargeFloat ).
self assert:( 2.0 asLargeFloat <= 2.0 asLargeFloat ).
1 to:1000 do:[:a |
0 to:a-1 do:[:b |
|fA fB|
self assert:(b < a).
self assert:(b <= a).
self assert:(a > b).
self assert:(a >= b).
self assert:(a ~= b).
self assert:(a = b) not.
fA := a asLargeFloat.
fB := b asLargeFloat.
self assert:(fB < fA).
self assert:(fB <= fA).
self assert:(fA > fB).
self assert:(fA >= fB).
self assert:(fA ~= fB).
self assert:(fA = fB) not.
].
].
1 asLargeFloat to:1000 asLargeFloat do:[:fA |
0 asLargeFloat to:fA-1 do:[:fB |
self assert:(fB < fA).
self assert:(fB <= fA).
self assert:(fA > fB).
self assert:(fA >= fB).
self assert:(fA ~= fB).
self assert:(fA = fB) not.
].
].
"
self basicNew test05_Comparing
"
"Modified (format): / 10-10-2017 / 15:20:37 / cg"
!
test06_MiscMath
#(
sqrt 100000.0
sqrt 1000.0
sqrt 100.0
sqrt 100
sqrt 2.0
sqrt 1.0
sqrt 0.5
sqrt 0.0
"/ exp 0.5
"/ ln 100.0
"/ ln 10.0
"/ ln 0.5
"/ log10 100.0
"/ log10 10.0
"/ log10 0.5
"/ sin 0.5
"/ cos 0.5
"/ tan 0.5
"/ arcSin 0.5
"/ arcCos 0.5
"/ arcTan 0.5
sinh 0.5
cosh 0.5
tanh 0.5
"/ arcSinh 0.5
"/ arcCosh 1.5
"/ arcTanh 0.5
) pairWiseDo:[:op :arg |
"/ self assert:( arg asLargeFloat perform:op ) class == LargeFloat.
( arg asLargeFloat perform:op ) class == LargeFloat ifFalse:[
Transcript showCR:'warning: missing LargeFloat function: ' , op.
].
self assert:( (arg perform:op) - (arg asLargeFloat perform:op) ) < 0.000001.
self assert:( (arg perform:op) - (arg perform:op) asLargeFloat ) < 0.000001.
].
"
self basicNew test06_MiscMath
"
"Modified: / 10-10-2017 / 12:54:52 / cg"
!
test07_Truncation
|check|
check := [:num |
self assert:( num fractionPart + num truncated ) = num.
self assert:( num fractionPart + num truncated ) class == num class.
].
check value:1.6 asLargeFloat.
check value:-1.6 asLargeFloat.
self assert:( 1.6 asLargeFloat ceiling ) = 2.
self assert:( 1.6 asLargeFloat ceilingAsFloat ) = 2.0 asLargeFloat.
self assert:( 1.6 asLargeFloat ceilingAsFloat ) class == LargeFloat.
self assert:( 1.6 asLargeFloat floor ) = 1.
self assert:( 1.6 asLargeFloat floorAsFloat ) = 1.0 asLargeFloat.
self assert:( 1.6 asLargeFloat floorAsFloat ) class == LargeFloat.
self assert:( 0.4 asLargeFloat rounded ) class == SmallInteger.
self assert:( 0.4 asLargeFloat rounded = 0 ).
self assert:( 0.5 asLargeFloat rounded = 1 ).
self assert:( 0.6 asLargeFloat rounded = 1 ).
self assert:( -0.4 asLargeFloat rounded = 0 ).
self assert:( -0.5 asLargeFloat rounded = -1 ).
self assert:( -0.6 asLargeFloat rounded = -1 ).
self assert:( 0.4 asLargeFloat roundedAsFloat ) class == LargeFloat.
self assert:( 0.4 asLargeFloat roundedAsFloat = 0.0 ).
self assert:( 0.5 asLargeFloat roundedAsFloat = 1.0 ).
self assert:( 0.6 asLargeFloat roundedAsFloat = 1.0 ).
self assert:( -0.4 asLargeFloat roundedAsFloat = 0 ).
self assert:( -0.5 asLargeFloat roundedAsFloat = -1.0 ).
self assert:( -0.6 asLargeFloat roundedAsFloat = -1.0 ).
self assert:( 0.4 truncated ) class == SmallInteger.
self assert:( 0.4 truncated = 0 ).
self assert:( 0.5 truncated = 0 ).
self assert:( 0.6 truncated = 0 ).
self assert:( -0.4 truncated = 0 ).
self assert:( -0.5 truncated = 0 ).
self assert:( -0.6 truncated = 0 ).
self assert:( 0.4 truncatedAsFloat ) class == Float.
self assert:( 0.4 truncatedAsFloat = 0.0 ).
self assert:( 0.5 truncatedAsFloat = 0.0 ).
self assert:( 0.6 truncatedAsFloat = 0.0 ).
self assert:( -0.4 truncatedAsFloat = 0 ).
self assert:( -0.5 truncatedAsFloat = 0.0 ).
self assert:( -0.6 truncatedAsFloat = 0.0 ).
self assert:( 0.4 asShortFloat truncated ) class == SmallInteger.
self assert:( 0.4 asShortFloat truncated = 0 ).
self assert:( 0.5 asShortFloat truncated = 0 ).
self assert:( 0.6 asShortFloat truncated = 0 ).
self assert:( -0.4 asShortFloat truncated = 0 ).
self assert:( -0.5 asShortFloat truncated = 0 ).
self assert:( -0.6 asShortFloat truncated = 0 ).
self assert:( 0.4 asShortFloat truncatedAsFloat ) class == ShortFloat.
self assert:( 0.4 asShortFloat truncatedAsFloat = 0.0 ).
self assert:( 0.5 asShortFloat truncatedAsFloat = 0.0 ).
self assert:( 0.6 asShortFloat truncatedAsFloat = 0.0 ).
self assert:( -0.4 asShortFloat truncatedAsFloat = 0 ).
self assert:( -0.5 asShortFloat truncatedAsFloat = 0.0 ).
self assert:( -0.6 asShortFloat truncatedAsFloat = 0.0 ).
self assert:( 0.4 asLargeFloat truncated ) class == SmallInteger.
self assert:( 0.4 asLargeFloat truncated = 0 ).
self assert:( 0.5 asLargeFloat truncated = 0 ).
self assert:( 0.6 asLargeFloat truncated = 0 ).
self assert:( -0.4 asLargeFloat truncated = 0 ).
self assert:( -0.5 asLargeFloat truncated = 0 ).
self assert:( -0.6 asLargeFloat truncated = 0 ).
self assert:( 0.4 asLargeFloat truncatedAsFloat ) class == LargeFloat.
self assert:( 0.4 asLargeFloat truncatedAsFloat = 0.0 ).
self assert:( 0.5 asLargeFloat truncatedAsFloat = 0.0 ).
self assert:( 0.6 asLargeFloat truncatedAsFloat = 0.0 ).
self assert:( -0.4 asLargeFloat truncatedAsFloat = 0 ).
self assert:( -0.5 asLargeFloat truncatedAsFloat = 0.0 ).
self assert:( -0.6 asLargeFloat truncatedAsFloat = 0.0 ).
"
self basicNew test07_Truncation
"
!
test08_Representation
self assert:( LargeFloat new
mantissa:1 exponent:1) printString = '2.0'.
self assert:( 0.0 asLargeFloat mantissa == 0).
self assert:( 0.0 asLargeFloat exponent == 0).
self assert:( 1.0 asLargeFloat mantissa == 1).
self assert:( 1.0 asLargeFloat exponent == 0).
self assert:( 2.0 asLargeFloat mantissa == 1).
self assert:( 2.0 asLargeFloat exponent == 1).
self assert:( 4.0 asLargeFloat mantissa == 1).
self assert:( 4.0 asLargeFloat exponent == 2).
self assert:( 5.0 asLargeFloat mantissa == 5).
self assert:( 5.0 asLargeFloat exponent == 0).
self assert:( 7.0 asLargeFloat mantissa == 7).
self assert:( 7.0 asLargeFloat exponent == 0).
self assert:( 14.0 asLargeFloat mantissa == 7).
self assert:( 14.0 asLargeFloat exponent == 1).
self assert:( 0.5 asLargeFloat mantissa == 1).
self assert:( 0.5 asLargeFloat exponent == -1).
self assert:( 0.25 asLargeFloat mantissa == 1).
self assert:( 0.25 asLargeFloat exponent == -2).
"
self basicNew test08_Representation
"
"Modified (format): / 10-10-2017 / 15:28:08 / cg"
!
test09_Testing
self assert:( 0.0 asLargeFloat isZero ).
self assert:( 1.0 asLargeFloat isZero not ).
self assert:( 0.0 asLargeFloat negative not ).
self assert:( 1.0 asLargeFloat negative not ).
self assert:( -1.0 asLargeFloat negative ).
self assert:( 0.0 asLargeFloat positive ).
self assert:( 1.0 asLargeFloat positive ).
self assert:( -1.0 asLargeFloat positive not ).
self assert:( 0.0 asLargeFloat strictlyPositive not ).
self assert:( 1.0 asLargeFloat strictlyPositive ).
self assert:( -1.0 asLargeFloat strictlyPositive not ).
self assert:( 0.0 asLargeFloat sign == 0 ).
self assert:( 1.0 asLargeFloat sign == 1 ).
self assert:( -1.0 asLargeFloat sign == -1 ).
"
self basicNew test09_Testing
"
!
test10_Printing
|fac50|
fac50 := (1 asLargeFloat to:50 asLargeFloat) product.
self assert:(fac50 printString = (50 factorial printString , '.0'))
"
self basicNew test10_Printing
"
"Created: / 10-10-2017 / 16:22:15 / cg"
! !
!LargeFloatTest class methodsFor:'documentation'!
version
^ '$Header$'
!
version_CVS
^ '$Header$'
! !