Re: [swift-users] FloatingPoint equality ..

2017-06-29 Thread David Sweeris via swift-users
I'd probably do this:
precedencegroup FauxTwoPartOperatorPrecedence {
  associativity: right
  higherThan: BitwiseShiftPrecedence
}
public struct VaE {
  var value: T
  var epsilon: T
}
infix operator ± : FauxTwoPartOperatorPrecedence // `±` is typed "shift-opt-=", 
at least with macOS's default QWERTY US keyboard layout
public func ±  (value: T, epsilon: T) -> VaE {
  return VaE(value: value, epsilon: epsilon)
}
public func ==  (lhs: T, rhs: VaE) -> Bool {
  return lhs <= (rhs.value + rhs.epsilon) && lhs >= (rhs.value - rhs.epsilon)
}

0.0 == 0.0 ± 0.1 // true
1.0 == 0.0 ± 0.1 // false
-0.3 == 0.0 ± 0.5 // true

(or use something like `+-`, if you prefer your custom operators to be not 
quite that custom)

Hope that helps,
- Dave Sweeris

> On Jun 29, 2017, at 2:20 PM, Gavin Eadie via swift-users 
>  wrote:
> 
> .. agreed but this looks too awful (and is mostly a joke!)
> 
> return a >= b.nextDown.nextDown.nextDown.nextDown && a <= 
> b.nextUp.nextUp.nextUp.nextUp
> 
> Thanks, friends, for your insights and info .. Gavin
> 
> On Thu, Jun 29, 2017 at 3:30 PM, Taylor Swift via swift-users 
> mailto:swift-users@swift.org>> wrote:
> 
> (b) one ULP is almost never a tolerance you want to use. It’s much too small 
> for almost all computations, and too large for most of the remaining ones.
> 
> – Steve
> 
> ___
> swift-users mailing list
> swift-users@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-users 
> 
> 
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] FloatingPoint equality ..

2017-06-29 Thread Gavin Eadie via swift-users
.. agreed but this looks too awful (and is mostly a joke!)

return a >= b.nextDown.nextDown.nextDown.nextDown && a <= b.nextUp.
nextUp.nextUp.nextUp

Thanks, friends, for your insights and info .. Gavin

On Thu, Jun 29, 2017 at 3:30 PM, Taylor Swift via swift-users <
swift-users@swift.org> wrote:

>
>> (b) one ULP is almost never a tolerance you want to use. It’s much too
>> small for almost all computations, and too large for most of the remaining
>> ones.
>>
>> – Steve
>>
>
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] FloatingPoint equality ..

2017-06-29 Thread Stephen Canon via swift-users


> On Jun 29, 2017, at 2:40 PM, Gavin Eadie via swift-users 
>  wrote:
> 
> I've spent a fascinating evening and morning in the arcane depths of floating 
> point, specifically researching the comparison of two floating point numbers. 
>  I pretty much understand how to do this with a combination of 'epsilon' and 
> 'ULPs' after reading this 
> .
> 
> For example, for a off-by-one ULP comparison:
> 
> public func almostEqual(_ a: Double, _ b: Double) -> Bool {
> return a == b ||
>a == nextafter(b, +.greatestFiniteMagnitude) ||
>a == nextafter(b, -.greatestFiniteMagnitude)
> }
> 
> My question is whether Swift has a built in method that provides an 'almost 
> equal' comparison?

It does not. It is “trivial” to implement such a comparison (just like you do 
here); the difficulty is entirely in guiding users in choosing a means of 
comparison and tolerance appropriate to their problem.

> Or, asking the same question another way, what doesn't the Swift method
> 
>  func isEqual(to other: Self) -> Bool 
> 
> 
> actually do?  Does it test for equality of the binary representation of 
> 'self' and 'other' (I assume it must given no 'precision' argument) .. I read 
> it follows the IEEE meaning of equality but that document is not on my 
> bookshelf and is quite expensive!

isEqual implements IEEE equality, which is *not the same* as bitwise equality 
of representation. In particular:

1. x != x is true when x is NaN.
2. –0 == +0, but the two values have different encodings.
3. Float80 admits non-canonical “pseudo denormal” values that compare equal to 
a canonical value with a different encoding.
4. IEEE 754 Decimal types (not implemented in the standard library) have *many* 
encodings that compare equal.

– Steve___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] FloatingPoint equality ..

2017-06-29 Thread Taylor Swift via swift-users
You can make it even simpler with a range pattern

func almost_equal(_ a:T, _ b:T) -> Bool
{
return b.nextDown ... b.nextUp ~= a
}

On Thu, Jun 29, 2017 at 3:05 PM, Stephen Canon via swift-users <
swift-users@swift.org> wrote:

> I should also point out:
>
> (a) your code can be somewhat simpler in Swift. I would probably write
> something along the lines of:
>
> func almostEqual(_ a: T, _ b: T) -> Bool {
> return a >= b.nextDown && a <= b.nextUp
> }
>
> (b) one ULP is almost never a tolerance you want to use. It’s much too
> small for almost all computations, and too large for most of the remaining
> ones.
>
> – Steve
>
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] FloatingPoint equality ..

2017-06-29 Thread Stephen Canon via swift-users
I should also point out:

(a) your code can be somewhat simpler in Swift. I would probably write 
something along the lines of:

func almostEqual(_ a: T, _ b: T) -> Bool {
return a >= b.nextDown && a <= b.nextUp
}

(b) one ULP is almost never a tolerance you want to use. It’s much too small 
for almost all computations, and too large for most of the remaining ones.

– Steve___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] FloatingPoint equality ..

2017-06-29 Thread Gavin Eadie via swift-users
I've spent a fascinating evening and morning in the arcane depths of
floating point, specifically researching the comparison of two floating
point numbers.  I pretty much understand how to do this with a combination
of 'epsilon' and 'ULPs' after reading this

.

For example, for a off-by-one ULP comparison:

public func almostEqual(_ a: Double, _ b: Double) -> Bool {

return a == b ||

   a == nextafter(b, +.greatestFiniteMagnitude) ||

   a == nextafter(b, -.greatestFiniteMagnitude)

}

My question is whether Swift has a built in method that provides an 'almost
equal' comparison?

Or, asking the same question another way, what doesn't the Swift method

 func isEqual(to other: Self) -> Bool


actually do?  Does it test for equality of the binary representation of
'self' and 'other' (I assume it must given no 'precision' argument) .. I
read it follows the IEEE meaning of equality but that document is not on my
bookshelf and is quite expensive!

Apologies if this has been asked and answered before .. Gavin
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users