2016-09-03 11:17 GMT+02:00 Denis Kudriashov <dionisi...@gmail.com>:
> > 2016-09-03 9:48 GMT+02:00 Nicolas Cellier <nicolas.cellier.aka.nice@ > gmail.com>: > >> For floating points it would be good to also have something related to >> unit of least precision like I think it exists in google tests: >> >> assert: aFloat isWithin: anInteger ulpFrom: anotherFloat >> ^(aFloat - anotherFloat) abs <= (anotherFloat ulp max: aFloat ulp) >> >> It's testing if the result are the same with a tolerance on least >> significant bits. >> (anotherFloat ulp max: aFloat ulp) is not really necessary, it's only for >> making the comparison symmetric. >> indeed, 2 and 2 predecessor do not have the same exponent, so do not have >> the same ulp. >> If we don't have symmetry, then >> self assert: 2.0 predecessor predecessor isWithin: 1 ulpFrom: 2.0. >> might differ from: >> self assert: 2.0 isWithin: 1 ulpFrom: 2.0 predecessor predecessor . >> >> Note that the this message cannot be used to test for zero result >> (because 0.0 ulp is the smallest denormal). >> For example: >> self assert: 2.0 - 2.0 predecessor isWithin: 4 ulpFrom: 0.0. >> would anwer false, but it makes no sense! >> One should write >> self assert: 2.0 isWithin: 4 ulpFrom: 2.0 predecessor. > > > Bad result will be in other cases too (not only zero): > > expected := 8085- 8084.9999. > computed := (80.85 * 100) - 8084.9999. > (computed - expected) abs <= (computed ulp max: expected ulp) "==> > false" > > > > Fine, this result is not within 1 ulp error because of catastrophic cancellation, the difference is more than 1e7 ulp. That just mean that we have a numerical formulation that is quite unstable (it has half precision of double). I don't see why this invalidate this specific type of assertion, au contraire.