diff --git a/OSBindings/Mac/Clock SignalTests/TimeTests.mm b/OSBindings/Mac/Clock SignalTests/TimeTests.mm index fc0e0615b..ad55cc965 100644 --- a/OSBindings/Mac/Clock SignalTests/TimeTests.mm +++ b/OSBindings/Mac/Clock SignalTests/TimeTests.mm @@ -34,4 +34,11 @@ XCTAssert(time == Storage::Time(0), @"Numbers too small to be represented should be 0"); } +- (void)testTooBigFloat +{ + float original = powf(2.0f, 48.0f); + Storage::Time time(original); + XCTAssert(time == Storage::Time::max(), @"Numbers too big to be represented should saturate"); +} + @end diff --git a/Storage/Storage.hpp b/Storage/Storage.hpp index 7220f8450..a0456870f 100644 --- a/Storage/Storage.hpp +++ b/Storage/Storage.hpp @@ -189,6 +189,11 @@ struct Time { clock_rate = 1; } + static Time max() + { + return Time(std::numeric_limits::max()); + } + private: inline void install_result(uint64_t long_length, uint64_t long_clock_rate) { @@ -207,14 +212,25 @@ struct Time { long_clock_rate /= common_divisor; // Okay, in desperation accept a loss of accuracy. - while(long_length > std::numeric_limits::max() || long_clock_rate > std::numeric_limits::max()) + while( + (long_length > std::numeric_limits::max() || long_clock_rate > std::numeric_limits::max()) && + (long_clock_rate > 1)) { long_length >>= 1; long_clock_rate >>= 1; } } - length = (unsigned int)long_length; - clock_rate = (unsigned int)long_clock_rate; + + if(long_length <= std::numeric_limits::max() && long_clock_rate <= std::numeric_limits::max()) + { + length = (unsigned int)long_length; + clock_rate = (unsigned int)long_clock_rate; + } + else + { + length = std::numeric_limits::max(); + clock_rate = 1u; + } } inline void install_float(float value)