Search code examples
swiftswift3nsrange

swift range greater than lower bound


I need to implement experience filter like this

  • 0 to 2 years
  • 2+ to 4 years

How to express it in swift range?

Problem is I can't express more than 2 to 4 years. While I can do less than upper bounds. e.g. like this

let underTen = 0.0..<10.0

I need something like this (greater than lower bound)

let uptoTwo = 0.0...2.0
let twoPlus = 2.0>..4.0  // compiler error

Currently I am doing

let twoPlus = 2.1...4.0

But this is not perfect.


Solution

  • nextUp from the FloatingPoint protocol

    You can make use of the nextUp property of Double, as blueprinted in the FloatingPoint protocol to which Double conforms

    nextUp

    The least representable value that compares greater than this value.

    For any finite value x, x.nextUp is greater than x. ...

    I.e.:

    let uptoTwo = 0.0...2.0
    let twoPlus = 2.0.nextUp...4.0
    

    The property ulp, also blueprinted in the FloatingPoint protocol, has been mentioned in the comments to your question. For most numbers, this is the difference between self and the next greater representable number:

    ulp

    The unit in the last place of self.

    This is the unit of the least significant digit in the significand of self. For most numbers x, this is the difference between x and the next greater (in magnitude) representable number. ...

    nextUp does, in essence, return the value of self with the addition of ulp. So for your example above, the following is equivalent (whereas, imo, nextup should be preferred in this use case).

    let uptoTwo = 0.0...2.0 
    let twoPlus = (2.0+2.0.ulp)...4.0
    

    You might also want to consider replacing the lower bound literal in twoPlus with the upperBound property of the preceding uptoTwo range:

    let uptoTwo = 0.0...2.0                       // [0, 2] closed-closed
    let twoPlus = uptoTwo.upperBound.nextUp...4.0 // (2, 4] open-closed
    
    if uptoTwo.overlaps(twoPlus) {
        print("the two ranges overlap ...")
    }
    else {
        print("ranges are non-overlapping, ok!")
    }
    // ranges are non-overlapping, ok!