Andreas Raab uploaded a new version of KernelTests to project The Trunk:
http://source.squeak.org/trunk/KernelTests-ar.171.mcz ==================== Summary ==================== Name: KernelTests-ar.171 Author: ar Time: 26 December 2010, 8:11:11.683 am UUID: 7d44d7be-dc5f-d042-b555-ea37e75d4ca1 Ancestors: KernelTests-ar.170 Merge FloatConsistencyTests for bit-identical floating point behavior. Fix FloatTest>>testDegree[Sin|Cos]ForExceptionalValues to use non-signaling NaNs otherwise the tests fail. =============== Diff against KernelTests-ul.168 =============== Item was added: + TestCase subclass: #FloatConsistencyTests + instanceVariableNames: 'random' + classVariableNames: '' + poolDictionaries: '' + category: 'KernelTests-Numbers'! Item was added: + ----- Method: FloatConsistencyTests>>copysign:from: (in category 'misc') ----- + copysign: x from: y + "Answer a float with the magnitude of x and the sign of y" + | copy word1 | + copy := x clone. + word1 := ((x basicAt: 1) bitAnd: 16r7FFFFFFF) bitOr: ((y asFloat basicAt: 1) bitAnd: 16r80000000). + copy basicAt: 1 put: word1. + ^copy! Item was added: + ----- Method: FloatConsistencyTests>>fillVector: (in category 'misc') ----- + fillVector: vector + + "Fill a given vector with the currently used random. Make sure we don't create NaNs etc." + + | bytes float | + bytes := ByteArray new: 4. + float := FloatArray new: 1. + 1 to: vector basicSize do:[:index| + [1 to: 4 do:[:k| bytes at: k put: (random nextInt: 256)-1]. + float basicAt: 1 put: (bytes unsignedLongAt: 1 bigEndian: true). + (float at: 1) isNaN] whileTrue. + vector basicAt: index put: (float basicAt: 1). + ]. + ^vector! Item was added: + ----- Method: FloatConsistencyTests>>floatTest: (in category 'misc') ----- + floatTest: aBlock + | bytes out float result hash | + random := Random seed: 253213. + bytes := ByteArray new: 8. + out := WriteStream on: ByteArray new. + float := Float basicNew: 2. + 1 to: 10000 do:[:i| + [1 to: 8 do:[:j| bytes at: j put: (random nextInt: 256)-1]. + float basicAt: 1 put: (bytes unsignedLongAt: 1 bigEndian: true). + float basicAt: 2 put: (bytes unsignedLongAt: 5 bigEndian: true). + float isNaN] whileTrue. + result := [aBlock value: float] on: Error do:[:ex| + "we convert all errors into NaNs to have a value for testing" + ex return: Float nan. + ]. + out nextNumber: 4 put: (result basicAt: 1). + out nextNumber: 4 put: (result basicAt: 2). + ]. + hash := self md5HashMessage: out contents. + result := LargePositiveInteger new: 16. + result replaceFrom: 1 to: 16 with: hash startingAt: 1. + ^result normalize! Item was added: + ----- Method: FloatConsistencyTests>>hashStream: (in category 'misc') ----- + hashStream: out + | hash result | + hash := self md5HashMessage: out contents. + result := LargePositiveInteger new: 16. + result replaceFrom: 1 to: 16 with: hash startingAt: 1. + ^result normalize! Item was added: + ----- Method: FloatConsistencyTests>>hashStreamFrom: (in category 'misc') ----- + hashStreamFrom: aBlock + + | out | + out := WriteStream on: (ByteArray new: 80000). + aBlock value: out. + ^self hashStream: out! Item was added: + ----- Method: FloatConsistencyTests>>md5Digest: (in category 'md5') ----- + md5Digest: aStringOrByteArray + "This creates a little endian hex string to be used with various auth methods + This is the same as htdigest (apache) uses for its md5 digest auth db" + + ^(self md5HashStream: (ReadStream on: aStringOrByteArray asByteArray)) reversed hex! Item was added: + ----- Method: FloatConsistencyTests>>md5Hash: (in category 'misc') ----- + md5Hash: arg + | hash large | + hash := self md5HashMessage: arg. + large := LargePositiveInteger new: 16. + large replaceFrom: 1 to: 16 with: hash startingAt: 1. + ^large normalize! Item was added: + ----- Method: FloatConsistencyTests>>md5HashMessage: (in category 'md5') ----- + md5HashMessage: aStringOrByteArray + "TCryptoRandom md5HashMessage: 'foo'" + ^ self md5HashStream: (ReadStream on: aStringOrByteArray asByteArray) + ! Item was added: + ----- Method: FloatConsistencyTests>>md5HashStream: (in category 'md5') ----- + md5HashStream: aStream + "self md5HashStream: (ReadStream on: 'foo')" + + | start buffer bytes sz n words hash | + hash := WordArray + with: 16r67452301 + with: 16rEFCDAB89 + with: 16r98BADCFE + with: 16r10325476. + words := WordArray new: 16. + buffer := ByteArray new: 64. + start := aStream position. + [aStream atEnd] whileFalse: [ + bytes := aStream nextInto: buffer. + (bytes size < 64 or:[aStream atEnd]) ifTrue:[ + sz := bytes size. + buffer replaceFrom: 1 to: sz with: bytes startingAt: 1. + buffer from: sz+1 to: buffer size put: 0. + sz < 56 ifTrue:[ + buffer at: sz + 1 put: 128. "trailing bit" + ] ifFalse:[ + "not enough room for the length, so just pad this one, then..." + sz < 64 ifTrue:[buffer at: sz + 1 put: 128]. + 1 to: 16 do:[:i| words at: i put: (buffer unsignedLongAt: i*4-3 bigEndian: false)]. + self md5Transform: words hash: hash. + "process one additional block of padding ending with the length" + buffer atAllPut: 0. + sz = 64 ifTrue: [buffer at: 1 put: 128]. + ]. + "Fill in the final 8 bytes with the 64-bit length in bits." + n := (aStream position - start) * 8. + 7 to: 0 by: -1 do:[:i| buffer at: (buffer size - i) put: ((n bitShift: 7 - i * -8) bitAnd: 255)]. + ]. + 1 to: 16 do:[:i| words at: i put: (buffer unsignedLongAt: i*4-3 bigEndian: false)]. + self md5Transform: words hash: hash. + ]. + bytes := ByteArray new: 16. + bytes unsignedLongAt: 1 put: (hash at: 4) bigEndian: true. + bytes unsignedLongAt: 5 put: (hash at: 3) bigEndian: true. + bytes unsignedLongAt: 9 put: (hash at: 2) bigEndian: true. + bytes unsignedLongAt: 13 put: (hash at: 1) bigEndian: true. + ^bytes + ! Item was added: + ----- Method: FloatConsistencyTests>>md5Transform:hash: (in category 'md5') ----- + md5Transform: in hash: hash + "This adds the incoming words to the existing hash" + + | a b c d | + <primitive: 'primitiveMD5Transform' module: 'CroquetPlugin'> + a := hash at: 1. + b := hash at: 2. + c := hash at: 3. + d := hash at: 4. + + a := self step1: a x: b y: c z: d data: (in at: 1) add: 16rD76AA478 shift: 7. + d := self step1: d x: a y: b z: c data: (in at: 2) add: 16rE8C7B756 shift: 12. + c := self step1: c x: d y: a z: b data: (in at: 3) add: 16r242070DB shift: 17. + b := self step1: b x: c y: d z: a data: (in at: 4) add: 16rC1BDCEEE shift: 22. + a := self step1: a x: b y: c z: d data: (in at: 5) add: 16rF57C0FAF shift: 7. + d := self step1: d x: a y: b z: c data: (in at: 6) add: 16r4787C62A shift: 12. + c := self step1: c x: d y: a z: b data: (in at: 7) add: 16rA8304613 shift: 17. + b := self step1: b x: c y: d z: a data: (in at: 8) add: 16rFD469501 shift: 22. + a := self step1: a x: b y: c z: d data: (in at: 9) add: 16r698098D8 shift: 7. + d := self step1: d x: a y: b z: c data: (in at: 10) add: 16r8B44F7AF shift: 12. + c := self step1: c x: d y: a z: b data: (in at: 11) add: 16rFFFF5BB1 shift: 17. + b := self step1: b x: c y: d z: a data: (in at: 12) add: 16r895CD7BE shift: 22. + a := self step1: a x: b y: c z: d data: (in at: 13) add: 16r6B901122 shift: 7. + d := self step1: d x: a y: b z: c data: (in at: 14) add: 16rFD987193 shift: 12. + c := self step1: c x: d y: a z: b data: (in at: 15) add: 16rA679438E shift: 17. + b := self step1: b x: c y: d z: a data: (in at: 16) add: 16r49B40821 shift: 22. + + a := self step2: a x: b y: c z: d data: (in at: 2) add: 16rF61E2562 shift: 5. + d := self step2: d x: a y: b z: c data: (in at: 7) add: 16rC040B340 shift: 9. + c := self step2: c x: d y: a z: b data: (in at: 12) add: 16r265E5A51 shift: 14. + b := self step2: b x: c y: d z: a data: (in at: 1) add: 16rE9B6C7AA shift: 20. + a := self step2: a x: b y: c z: d data: (in at: 6) add: 16rD62F105D shift: 5. + d := self step2: d x: a y: b z: c data: (in at: 11) add: 16r02441453 shift: 9. + c := self step2: c x: d y: a z: b data: (in at: 16) add: 16rD8A1E681 shift: 14. + b := self step2: b x: c y: d z: a data: (in at: 5) add: 16rE7D3FBC8 shift: 20. + a := self step2: a x: b y: c z: d data: (in at: 10) add: 16r21E1CDE6 shift: 5. + d := self step2: d x: a y: b z: c data: (in at: 15) add: 16rC33707D6 shift: 9. + c := self step2: c x: d y: a z: b data: (in at: 4) add: 16rF4D50D87 shift: 14. + b := self step2: b x: c y: d z: a data: (in at: 9) add: 16r455A14ED shift: 20. + a := self step2: a x: b y: c z: d data: (in at: 14) add: 16rA9E3E905 shift: 5. + d := self step2: d x: a y: b z: c data: (in at: 3) add: 16rFCEFA3F8 shift: 9. + c := self step2: c x: d y: a z: b data: (in at: 8) add: 16r676F02D9 shift: 14. + b := self step2: b x: c y: d z: a data: (in at: 13) add: 16r8D2A4C8A shift: 20. + + a := self step3: a x: b y: c z: d data: (in at: 6) add: 16rFFFA3942 shift: 4. + d := self step3: d x: a y: b z: c data: (in at: 9) add: 16r8771F681 shift: 11. + c := self step3: c x: d y: a z: b data: (in at: 12) add: 16r6D9D6122 shift: 16. + b := self step3: b x: c y: d z: a data: (in at: 15) add: 16rFDE5380C shift: 23. + a := self step3: a x: b y: c z: d data: (in at: 2) add: 16rA4BEEA44 shift: 4. + d := self step3: d x: a y: b z: c data: (in at: 5) add: 16r4BDECFA9 shift: 11. + c := self step3: c x: d y: a z: b data: (in at: 8) add: 16rF6BB4B60 shift: 16. + b := self step3: b x: c y: d z: a data: (in at: 11) add: 16rBEBFBC70 shift: 23. + a := self step3: a x: b y: c z: d data: (in at: 14) add: 16r289B7EC6 shift: 4. + d := self step3: d x: a y: b z: c data: (in at: 1) add: 16rEAA127FA shift: 11. + c := self step3: c x: d y: a z: b data: (in at: 4) add: 16rD4EF3085 shift: 16. + b := self step3: b x: c y: d z: a data: (in at: 7) add: 16r04881D05 shift: 23. + a := self step3: a x: b y: c z: d data: (in at: 10) add: 16rD9D4D039 shift: 4. + d := self step3: d x: a y: b z: c data: (in at: 13) add: 16rE6DB99E5 shift: 11. + c := self step3: c x: d y: a z: b data: (in at: 16) add: 16r1FA27CF8 shift: 16. + b := self step3: b x: c y: d z: a data: (in at: 3) add: 16rC4AC5665 shift: 23. + + a := self step4: a x: b y: c z: d data: (in at: 1) add: 16rF4292244 shift: 6. + d := self step4: d x: a y: b z: c data: (in at: 8) add: 16r432AFF97 shift: 10. + c := self step4: c x: d y: a z: b data: (in at: 15) add: 16rAB9423A7 shift: 15. + b := self step4: b x: c y: d z: a data: (in at: 6) add: 16rFC93A039 shift: 21. + a := self step4: a x: b y: c z: d data: (in at: 13) add: 16r655B59C3 shift: 6. + d := self step4: d x: a y: b z: c data: (in at: 4) add: 16r8F0CCC92 shift: 10. + c := self step4: c x: d y: a z: b data: (in at: 11) add: 16rFFEFF47D shift: 15. + b := self step4: b x: c y: d z: a data: (in at: 2) add: 16r85845DD1 shift: 21. + a := self step4: a x: b y: c z: d data: (in at: 9) add: 16r6FA87E4F shift: 6. + d := self step4: d x: a y: b z: c data: (in at: 16) add: 16rFE2CE6E0 shift: 10. + c := self step4: c x: d y: a z: b data: (in at: 7) add: 16rA3014314 shift: 15. + b := self step4: b x: c y: d z: a data: (in at: 14) add: 16r4E0811A1 shift: 21. + a := self step4: a x: b y: c z: d data: (in at: 5) add: 16rF7537E82 shift: 6. + d := self step4: d x: a y: b z: c data: (in at: 12) add: 16rBD3AF235 shift: 10. + c := self step4: c x: d y: a z: b data: (in at: 3) add: 16r2AD7D2BB shift: 15. + b := self step4: b x: c y: d z: a data: (in at: 10) add: 16rEB86D391 shift: 21. + + a := (a + (hash at: 1)) bitAnd: 16rFFFFFFFF. hash at: 1 put: a. + b := (b + (hash at: 2)) bitAnd: 16rFFFFFFFF. hash at: 2 put: b. + c := (c + (hash at: 3)) bitAnd: 16rFFFFFFFF. hash at: 3 put: c. + d := (d + (hash at: 4)) bitAnd: 16rFFFFFFFF. hash at: 4 put: d. + + ^hash! Item was added: + ----- Method: FloatConsistencyTests>>processResult:stream: (in category 'misc') ----- + processResult: result stream: out + + "Process the result of a computation" + | v | + v := result ifNil:[Float nan]. + 1 to: v basicSize do:[:idx| out nextNumber: 4 put: (v basicAt: idx)]. + ! Item was added: + ----- Method: FloatConsistencyTests>>rotate:by: (in category 'md5') ----- + rotate: value by: amount + "Rotate value left by amount" + + | lowMask highMask | + lowMask := (1 bitShift: 32-amount) - 1. + highMask := 16rFFFFFFFF - lowMask. + ^((value bitAnd: lowMask) bitShift: amount) + + ((value bitAnd: highMask) bitShift: amount-32)! Item was added: + ----- Method: FloatConsistencyTests>>step1:x:y:z:data:add:shift: (in category 'md5') ----- + step1: w x: x y: y z: z data: data add: add shift: s + "Step 1 in MD5 transformation" + + | f result | + f := z bitXor: (x bitAnd: (y bitXor: z)). + result := w + f + data + add. + result := self rotate: result by: s. + ^result + x bitAnd: 16rFFFFFFFF! Item was added: + ----- Method: FloatConsistencyTests>>step2:x:y:z:data:add:shift: (in category 'md5') ----- + step2: w x: x y: y z: z data: data add: add shift: s + "Step 2 in MD5 transformation" + + | f result | + f := y bitXor: (z bitAnd: (x bitXor: y)). + result := w + f + data + add. + result := self rotate: result by: s. + ^result + x bitAnd: 16rFFFFFFFF! Item was added: + ----- Method: FloatConsistencyTests>>step3:x:y:z:data:add:shift: (in category 'md5') ----- + step3: w x: x y: y z: z data: data add: add shift: s + "Step 3 in MD5 transformation" + + | f result | + f := (x bitXor: y) bitXor: z. + result := w + f + data + add. + result := self rotate: result by: s. + ^result + x bitAnd: 16rFFFFFFFF! Item was added: + ----- Method: FloatConsistencyTests>>step4:x:y:z:data:add:shift: (in category 'md5') ----- + step4: w x: x y: y z: z data: data add: add shift: s + "Step 4 in MD5 transformation" + + | f result | + f := y bitXor: (x bitOr: (z bitXor: 16rFFFFFFFF)). + result := w + f + data + add. + result := self rotate: result by: s. + ^result + x bitAnd: 16rFFFFFFFF! Item was added: + ----- Method: FloatConsistencyTests>>testAddArray (in category 'array tests') ----- + testAddArray + | hash | + hash := self vectorVectorTest:[:v1 :v2 | v1 primAddArray: v2]. + self assert: hash = 144077765882344459641544075160959206703 + ! Item was added: + ----- Method: FloatConsistencyTests>>testAddScalar (in category 'array tests') ----- + testAddScalar + | hash | + hash := self vectorScalarTest:[:v1 :s2 | v1 primAddScalar: s2]. + self assert: hash = 126267177490805695389975970148750710209! Item was added: + ----- Method: FloatConsistencyTests>>testArcCos (in category 'float tests') ----- + testArcCos + | hash | + hash := self floatTest:[:f| f arcCos]. + self assert: hash = 320603091210691421897131240956682310429! Item was added: + ----- Method: FloatConsistencyTests>>testArcCosH (in category 'float tests') ----- + testArcCosH + | hash | + hash := self floatTest:[:f| f arcCosH]. + self assert: hash = 6724426144112251941037505276242428134! Item was added: + ----- Method: FloatConsistencyTests>>testArcCosHStd (in category 'float tests') ----- + testArcCosHStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. nil. nil }. + { 1.0. '0000000000000000'. nil }. + { 2.0. '3FF5124271980434'. nil }. + { Float infinity. '7FF0000000000000'. nil }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA arcCosH hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB arcCosH hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testArcCosStd (in category 'float tests') ----- + testArcCosStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '3FF921FB54442D18'. '3FF921FB54442D18' }. + { 1.0. '0000000000000000'. '400921FB54442D18' }. + { 2.0. nil. nil }. + { Float infinity. nil. nil }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA arcCos hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB arcCos hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testArcSin (in category 'float tests') ----- + testArcSin + | hash | + hash := self floatTest:[:f| f arcSin]. + self assert: hash = 27372132577303862731837100895783885417! Item was added: + ----- Method: FloatConsistencyTests>>testArcSinH (in category 'float tests') ----- + testArcSinH + | hash | + hash := self floatTest:[:f| f arcSinH]. + self assert: hash = 255911863578190171815115260235896145802! Item was added: + ----- Method: FloatConsistencyTests>>testArcSinHStd (in category 'float tests') ----- + testArcSinHStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '0000000000000000'. '8000000000000000' }. + { 1.0. '3FEC34366179D427'. 'BFEC34366179D427' }. + { 2.0. '3FF719218313D087'. 'BFF719218313D087' }. + { Float infinity. '7FF0000000000000'. 'FFF0000000000000' }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA arcSinH hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB arcSinH hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testArcSinStd (in category 'float tests') ----- + testArcSinStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '0000000000000000'. '8000000000000000' }. + { 1.0. '3FF921FB54442D18'. 'BFF921FB54442D18' }. + { 2.0. nil. nil }. + { Float infinity. nil. nil }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA arcSin hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB arcSin hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ]. + ! Item was added: + ----- Method: FloatConsistencyTests>>testArcTan (in category 'float tests') ----- + testArcTan + | hash | + hash := self floatTest:[:f| f arcTan]. + self assert: hash = 17311773710959114634056077345168823659! Item was added: + ----- Method: FloatConsistencyTests>>testArcTan2 (in category 'float tests') ----- + testArcTan2 + | hash | + hash := self floatTest:[:f| f arcTan: f]. + self assert: hash = 287068347279655848752274030373495709564! Item was added: + ----- Method: FloatConsistencyTests>>testArcTanH (in category 'float tests') ----- + testArcTanH + | hash | + hash := self floatTest:[:f| f arcTanH]. + self assert: hash = 295711907369004359459882231908879164929! Item was added: + ----- Method: FloatConsistencyTests>>testArcTanHStd (in category 'float tests') ----- + testArcTanHStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '0000000000000000'. '8000000000000000' }. + { 1.0. '7FF0000000000000'. 'FFF0000000000000' }. + { 2.0. nil. nil }. + { Float infinity. nil. nil }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA arcTanH hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB arcTanH hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testArcTanStd (in category 'float tests') ----- + testArcTanStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '0000000000000000'. '8000000000000000' }. + { 1.0. '3FE921FB54442D18'. 'BFE921FB54442D18' }. + { 2.0. '3FF1B6E192EBBE44'. 'BFF1B6E192EBBE44' }. + { Float infinity. '3FF921FB54442D18'. 'BFF921FB54442D18' }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA arcTan hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB arcTan hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testCos (in category 'float tests') ----- + testCos + | hash | + hash := self floatTest:[:f| f cos]. + self assert: hash = 110207739557966732640546618158077332978! Item was added: + ----- Method: FloatConsistencyTests>>testCosH (in category 'float tests') ----- + testCosH + | hash | + hash := self floatTest:[:f| f cosH]. + self assert: hash = 139309299067563830037108641802292492276! Item was added: + ----- Method: FloatConsistencyTests>>testCosHStd (in category 'float tests') ----- + testCosHStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '3FF0000000000000'. '3FF0000000000000' }. + { 1.0. '3FF8B07551D9F551'. '3FF8B07551D9F551' }. + { 2.0. '400E18FA0DF2D9BC'. '400E18FA0DF2D9BC' }. + { Float infinity. '7FF0000000000000'. '7FF0000000000000' }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA cosH hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB cosH hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ]. + ! Item was added: + ----- Method: FloatConsistencyTests>>testCosStd (in category 'float tests') ----- + testCosStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '3FF0000000000000'. '3FF0000000000000' }. + { 1.0. '3FE14A280FB5068C'. '3FE14A280FB5068C' }. + { 2.0. 'BFDAA22657537205'. 'BFDAA22657537205' }. + { Float infinity. nil. nil }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA cos hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB cos hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testDivArray (in category 'array tests') ----- + testDivArray + | hash | + hash := self vectorVectorTest:[:v1 :v2 | v1 primDivArray: v2]. + self assert: hash = 80910096946457615204728914361076966320! Item was added: + ----- Method: FloatConsistencyTests>>testDivScalar (in category 'array tests') ----- + testDivScalar + | hash | + hash := self vectorScalarTest:[:v1 :s2 | v1 primDivScalar: s2]. + self assert: hash = 570414977257248905680389076010819095! Item was added: + ----- Method: FloatConsistencyTests>>testDot (in category 'array tests') ----- + testDot + | hash | + hash := self vectorVectorTest:[:v1 :v2| v1 dot: v2]. + self assert: hash = 150216110228183805275896904027737941670. + ! Item was added: + ----- Method: FloatConsistencyTests>>testExp (in category 'float tests') ----- + testExp + | hash | + hash := self floatTest:[:f| f exp]. + self assert: hash = 264681209343177480335132131244505189510! Item was added: + ----- Method: FloatConsistencyTests>>testExpStd (in category 'float tests') ----- + testExpStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '3FF0000000000000'. '3FF0000000000000' }. + { 1.0. '4005BF0A8B14576A'. '3FD78B56362CEF38' }. + { 2.0. '401D8E64B8D4DDAE'. '3FC152AAA3BF81CC' }. + { Float infinity. '7FF0000000000000'. '0000000000000000' }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA exp hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB exp hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testFloatAt (in category 'float tests') ----- + testFloatAt + | hash flt | + flt := FloatArray new: 1. + hash := self floatTest:[:f| flt at: 1 put: f. flt at: 1]. + self assert: hash = 80498428122197125691266588764018905399! Item was added: + ----- Method: FloatConsistencyTests>>testFraction (in category 'float tests') ----- + testFraction + | hash | + hash := self floatTest:[:f| f fractionPart]. + self assert: hash = 320444785026869345695277323179170692004! Item was added: + ----- Method: FloatConsistencyTests>>testFractionStd (in category 'float tests') ----- + testFractionStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '0000000000000000'. '8000000000000000' }. + { 1.0. '0000000000000000'. '8000000000000000' }. + { 2.0. '0000000000000000'. '8000000000000000' }. + { Float infinity. '0000000000000000'. '8000000000000000' }. + { Float nan. '0000000000000000'. '8000000000000000' }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA fractionPart hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB fractionPart hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testHypot (in category 'float tests') ----- + testHypot + | hash | + hash := self floatTest:[:f| f hypot: f+1]. + self assert: hash = 217113721886532765853628735806816720346! Item was added: + ----- Method: FloatConsistencyTests>>testLength (in category 'array tests') ----- + testLength + | hash | + hash := self vectorTest:[:v1 | v1 length]. + self assert: hash = 207819694258655476491684678225238920813. + ! Item was added: + ----- Method: FloatConsistencyTests>>testLog (in category 'float tests') ----- + testLog + | hash | + hash := self floatTest:[:f| f abs ln]. + self assert: hash = 24389651894375564945708989023746058645! Item was added: + ----- Method: FloatConsistencyTests>>testLog10 (in category 'float tests') ----- + testLog10 + | hash | + hash := self floatTest:[:f| f abs log]. + self assert: hash = 135564553959509933253581837789050718785! Item was added: + ----- Method: FloatConsistencyTests>>testMD5 (in category 'md5') ----- + testMD5 + "Ensure that MD5 primitive works properly" + self assert: (self md5Hash: 'a') = 16r0CC175B9C0F1B6A831C399E269772661. + self assert: (self md5Hash: 'abc') = 16r900150983CD24FB0D6963F7D28E17F72. + self assert: (self md5Hash: 'message digest') = 16rF96B697D7CB7938D525A2F31AAF161D0. + self assert: (self md5Hash: + 'abcdefghijklmnopqrstuvwxyz') = 16rC3FCD3D76192E4007DFB496CCA67E13B. + self assert: (self md5Hash: + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') = + 16rD174AB98D277D9F5A5611C2C9F419D9F. + self assert: (self md5Hash: + '12345678901234567890123456789012345678901234567890123456789012345678901234567890') = + 16r57EDF4A22BE3C955AC49DA2E2107B67A.! Item was added: + ----- Method: FloatConsistencyTests>>testMulArray (in category 'array tests') ----- + testMulArray + | hash | + hash := self vectorVectorTest:[:v1 :v2 | v1 primMulArray: v2]. + self assert: hash = 94461360565991184554489439948329954948.! Item was added: + ----- Method: FloatConsistencyTests>>testMulScalar (in category 'array tests') ----- + testMulScalar + | hash | + hash := self vectorScalarTest:[:v1 :s2 | v1 primMulScalar: s2]. + self assert: hash = 96993460842141496093782297636277905186.! Item was added: + ----- Method: FloatConsistencyTests>>testNormalize (in category 'array tests') ----- + testNormalize + | hash | + hash := self vectorTest:[:v1 | v1 normalize]. + self assert: hash = 65842048927401502845374601234836342571.! Item was added: + ----- Method: FloatConsistencyTests>>testSin (in category 'float tests') ----- + testSin + | hash | + hash := self floatTest:[:f| f sin]. + self assert: hash = 290162321010315440569513182938961037473! Item was added: + ----- Method: FloatConsistencyTests>>testSinH (in category 'float tests') ----- + testSinH + | hash | + hash := self floatTest:[:f| f sinH]. + self assert: hash = 146029709156303766079448006055284064911! Item was added: + ----- Method: FloatConsistencyTests>>testSinHStd (in category 'float tests') ----- + testSinHStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '0000000000000000'. '8000000000000000' }. + { 1.0. '3FF2CD9FC44EB982'. 'BFF2CD9FC44EB982' }. + { 2.0. '400D03CF63B6E1A0'. 'C00D03CF63B6E1A0' }. + { Float infinity. '7FF0000000000000'. 'FFF0000000000000' }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA sinH hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB sinH hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testSinStd (in category 'float tests') ----- + testSinStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '0000000000000000'. '8000000000000000' }. + { 1.0. '3FEAED548F090CEE'. 'BFEAED548F090CEE' }. + { 2.0. '3FED18F6EAD1B446'. 'BFED18F6EAD1B446' }. + { Float infinity. nil. nil }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA sin hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB sin hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testSqrt (in category 'float tests') ----- + testSqrt + | hash | + hash := self floatTest:[:f| f abs sqrt]. + self assert: hash = 112236588358122834093969606123302196127! Item was added: + ----- Method: FloatConsistencyTests>>testSubArray (in category 'array tests') ----- + testSubArray + | hash | + hash := self vectorVectorTest:[:v1 :v2 | v1 primSubArray: v2]. + self assert: hash = 323016603234339452406622037180620109569.! Item was added: + ----- Method: FloatConsistencyTests>>testSubScalar (in category 'array tests') ----- + testSubScalar + | hash | + hash := self vectorScalarTest:[:v1 :s2 | v1 primSubScalar: s2]. + self assert: hash = 21245234269319054796422814018775160740.! Item was added: + ----- Method: FloatConsistencyTests>>testSum (in category 'array tests') ----- + testSum + | hash | + hash := self vectorTest:[:v1 | v1 sum]. + self assert: hash = 194048354065558535734705735684824571405.! Item was added: + ----- Method: FloatConsistencyTests>>testTan (in category 'float tests') ----- + testTan + | hash | + hash := self floatTest:[:f| f tan]. + self assert: hash = 207143885112027702205238433494882679660! Item was added: + ----- Method: FloatConsistencyTests>>testTanH (in category 'float tests') ----- + testTanH + | hash | + hash := self floatTest:[:f| f tanH]. + self assert: hash = 15738508136206638425252880299326548123! Item was added: + ----- Method: FloatConsistencyTests>>testTanHStd (in category 'float tests') ----- + testTanHStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + + "ar 4/19/2006: I have disabled the test for tanh(-0.0) for the time being because it was literally the 'last bit' differing amongst the various VMs before Croquet 1.0 and we were all wiped out by the time we ran into it to the point that I felt that having a different result for tan(-0.0) (-0.0 on some and 0.0 on other platforms with -0.0 being the 'correct' answer) wasn't worth pushing it any further. At some point we'll put it back in (likely before the next release; by then we'll have recovered from this one ;-) and fix it for good." + + " { 0.0. '0000000000000000'. '8000000000000000' }. " + { 1.0. '3FE85EFAB514F394'. 'BFE85EFAB514F394' }. + { 2.0. '3FEED9505E1BC3D4'. 'BFEED9505E1BC3D4' }. + { Float infinity. '3FF0000000000000'. 'BFF0000000000000' }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA tanH hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB tanH hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testTanStd (in category 'float tests') ----- + testTanStd + | inputA resultA inputB resultB | + { "test input value" "test result plus" "test result minus" + { 0.0. '0000000000000000'. '8000000000000000' }. + { 1.0. '3FF8EB245CBEE3A6'. 'BFF8EB245CBEE3A6' }. + { 2.0. 'C0017AF62E0950F8'. '40017AF62E0950F8' }. + { Float infinity. nil. nil }. + { Float nan. nil. nil }. + } do:[:spec| + inputA := self copysign: spec first from: 1.0. + resultA := [inputA tan hex] on: Error do:[:ex| ex return: nil]. + inputB := self copysign: spec first from: -1.0. + resultB := [inputB tan hex] on: Error do:[:ex| ex return: nil]. + self assert: spec second = resultA. + self assert: spec third = resultB. + ].! Item was added: + ----- Method: FloatConsistencyTests>>testTimesTwoPower (in category 'float tests') ----- + testTimesTwoPower + | hash | + hash := self floatTest:[:f| f timesTwoPower: (random nextInt: 200) - 100]. + self assert: hash = 278837335583284459890979576373223649870.! Item was added: + ----- Method: FloatConsistencyTests>>vectorScalarTest: (in category 'misc') ----- + vectorScalarTest: aBlock + ^self hashStreamFrom: [:out| self vectorScalarTest: aBlock on: out]! Item was added: + ----- Method: FloatConsistencyTests>>vectorScalarTest:on: (in category 'misc') ----- + vectorScalarTest: aBlock on: aStream + + | arg1 arg2 result | + random := Random seed: 253213. + arg1 := FloatArray new: 3. + arg2 := Float basicNew: 2. + 1 to: 10000 do:[:i| + [result := [aBlock value: (self fillVector: arg1) + value: (self fillVector: arg2)] on: Error do:[:ex| ex return: nil]. + self processResult: result stream: aStream. + result == nil] whileTrue. + ]! Item was added: + ----- Method: FloatConsistencyTests>>vectorTest: (in category 'misc') ----- + vectorTest: aBlock + + | out arg1 result | + random := Random seed: 253213. + out := WriteStream on: ByteArray new. + arg1 := FloatArray new: 3. + 1 to: 10000 do:[:i| + [result := [aBlock value: (self fillVector: arg1)] on: Error do:[:ex| ex return: nil]. + self processResult: result stream: out. + result == nil] whileTrue. + ]. + ^self hashStream: out! Item was added: + ----- Method: FloatConsistencyTests>>vectorVectorTest: (in category 'misc') ----- + vectorVectorTest: aBlock + ^self hashStreamFrom: [:out| self vectorVectorTest: aBlock on: out]! Item was added: + ----- Method: FloatConsistencyTests>>vectorVectorTest:on: (in category 'misc') ----- + vectorVectorTest: aBlock on: aStream + + | arg1 arg2 result | + random := Random seed: 253213. + arg1 := FloatArray new: 3. + arg2 := FloatArray new: 3. + 1 to: 10000 do:[:i| + [result := [aBlock value: (self fillVector: arg1) + value: (self fillVector: arg2)] on: Error do:[:ex| ex pass]. + self processResult: result stream: aStream. + result == nil] whileTrue. + ]! Item was changed: ----- Method: FloatTest>>testDegreeCosForExceptionalValues (in category 'test - mathematical functions') ----- testDegreeCosForExceptionalValues + | signaling | + signaling := Float signalNaN. + [Float signalNaN: false. self assert: Float nan degreeCos isNaN. self assert: Float infinity degreeCos isNaN. + self assert: Float infinity negated degreeCos isNaN. + ] ensure:[Float signalNaN: signaling]. + ! - self assert: Float infinity negated degreeCos isNaN.! Item was changed: ----- Method: FloatTest>>testDegreeSinForExceptionalValues (in category 'test - mathematical functions') ----- testDegreeSinForExceptionalValues + | signaling | + signaling := Float signalNaN. + [Float signalNaN: false. self assert: Float nan degreeSin isNaN. self assert: Float infinity degreeSin isNaN. + self assert: Float infinity negated degreeSin isNaN. + ] ensure:[Float signalNaN: signaling].! - self assert: Float infinity negated degreeSin isNaN.! Item was added: + ----- Method: FloatTest>>testNonSignalingNaN (in category 'NaN behavior') ----- + testNonSignalingNaN + "Ensure that NaNs signal when signaling NaNs are enabled" + | setting nan | + setting := Float signalNaN. + nan := Float nan. + [Float signalNaN: false. + + self shouldnt:[self assert: nan arcCos isNaN] raise: NaNError. + self shouldnt:[self assert: nan arcCosH isNaN] raise: NaNError. + self shouldnt:[self assert: nan arcSin isNaN] raise: NaNError. + self shouldnt:[self assert: nan arcSinH isNaN] raise: NaNError. + self shouldnt:[self assert: nan arcTan isNaN] raise: NaNError. + self shouldnt:[self assert: (nan arcTan: 1.0) isNaN] raise: NaNError. + self shouldnt:[self assert: (1.0 arcTan: nan) isNaN] raise: NaNError. + self shouldnt:[self assert: (nan arcTan: nan) isNaN] raise: NaNError. + self shouldnt:[self assert: nan arcTanH isNaN] raise: NaNError. + self shouldnt:[self assert: nan cos isNaN] raise: NaNError. + self shouldnt:[self assert: nan cosH isNaN] raise: NaNError. + self shouldnt:[self assert: nan exp isNaN] raise: NaNError. + self shouldnt:[self assert: (nan hypot: 1.0) isNaN] raise: NaNError. + self shouldnt:[self assert: (1.0 hypot: nan) isNaN] raise: NaNError. + self shouldnt:[self assert: (nan hypot: nan) isNaN] raise: NaNError. + self shouldnt:[self assert: nan ln isNaN] raise: NaNError. + self shouldnt:[self assert: nan log isNaN] raise: NaNError. + self shouldnt:[self assert: nan sin isNaN] raise: NaNError. + self shouldnt:[self assert: nan sinH isNaN] raise: NaNError. + self shouldnt:[self assert: nan tan isNaN] raise: NaNError. + self shouldnt:[self assert: nan tanH isNaN] raise: NaNError. + self shouldnt:[self assert: (nan timesTwoPower: 2) isNaN] raise: NaNError. + + ] ensure:[Float signalNaN: setting].! Item was added: + ----- Method: FloatTest>>testSignalingNaN (in category 'NaN behavior') ----- + testSignalingNaN + "Ensure that NaNs signal when signaling NaNs are enabled" + | setting nan | + setting := Float signalNaN. + nan := Float nan. + [Float signalNaN: true. + + self should:[nan arcCos] raise: NaNError. + self should:[nan arcCosH] raise: NaNError. + self should:[nan arcSin] raise: NaNError. + self should:[nan arcSinH] raise: NaNError. + self should:[nan arcTan] raise: NaNError. + self should:[nan arcTan: 1.0] raise: NaNError. + self should:[1.0 arcTan: nan] raise: NaNError. + self should:[nan arcTan: nan] raise: NaNError. + self should:[nan arcTanH] raise: NaNError. + self should:[nan cos] raise: NaNError. + self should:[nan cosH] raise: NaNError. + self should:[nan exp] raise: NaNError. + self should:[nan hypot: 1.0] raise: NaNError. + self should:[1.0 hypot: nan] raise: NaNError. + self should:[nan hypot: nan] raise: NaNError. + self should:[nan ln] raise: NaNError. + self should:[nan log] raise: NaNError. + self should:[nan sin] raise: NaNError. + self should:[nan sinH] raise: NaNError. + self should:[nan tan] raise: NaNError. + self should:[nan tanH] raise: NaNError. + self should:[nan timesTwoPower: 2] raise: NaNError. + + ] ensure:[Float signalNaN: setting].! |
Free forum by Nabble | Edit this page |