Declan McKenna
Declan McKenna

Reputation: 4870

Generic Numeric parameters

Is it possible to convert any integer value in to a Double using generics? I'd like to make this function a bit more convenient so I can jam any number in here without having to convert the hour and minute arguments I pass in to Doubles. Mostly just to get my head around generics more than anything else.

Looking in to Double's documentation the closest thing I can find is Double(exactly: T) but it gives me an optional value while I can't find any protocols that will both support the + and * operators and allow me to convert to a Double. I'd like to do this without creating my own protocol if it's possible.

This doesn't work but illustrates what I'm trying to do:

///Returns a Date object for today set to a given time on a 24 hour clock
private func today<T: SignedInteger>(hour: T = 0, minute: T = 0, second: T = 0) -> Date {
    let secondsPastMidnight: Double = Double(exactly: hour)! * 60 * 60 + Double(exactly: minute)! * 60 + Double(exactly: second)!
    return Date().startOfDay.addingTimeInterval(secondsPastMidnight)
}

Calling the above like so:

let superEarlyMeeting = Meeting(UUID: "0", startTime: today(), endTime: today(hour: SharedGlobals.Calendar.WORK_HOURS_START))

Give an error for: Generic parameter 'T' could not be inferred

Upvotes: 1

Views: 65

Answers (1)

Martin R
Martin R

Reputation: 539845

Double(exactly:) fails if the integer is not exactly representable as a 64-bit IEEE-754 floating point number, i.e. for integers greater or equal to 9,007,199,254,740,993 in magnitude, that should not be a problem when working with hours, minutes, and seconds. (Actually it does not fail at all, which is a bug).

Alternatively you can convert via the largest signed integer type, e.g.

Double(Int64(hour))

which returns the closest representable floating point number as a non-optional.

Upvotes: 1

Related Questions