Swift 3:fatal error: Double value cannot be converted to Int because it is either infinite or NaN
You should check if totalSeconds
is a valid value, like:
guard !(totalsSeconds.isNaN || totalSeconds.isInfinite) else {
return "illegal value" // or do some error handling
}
And check this:
Convert Float to Int in Swift
Receiving Fatal error: Double value cannot be converted to Int because it is either infinite or NaN
From the CMTimeGetSeconds
documentation:
If the CMTime is invalid or indefinite, NaN is returned. If the CMTime
is infinite, +/- infinity is returned.
When CMTimeGetSeconds
returns NaN or infinity, casting the return value to an Int
will throw the Fatal Error you are seeing.
You can first check the value then return some sort of default in case it's not a valid number.
func toDisplayString() -> String {
let rawSeconds = CMTimeGetSeconds(self)
guard !(rawSeconds.isNaN || rawSeconds.isInfinite) else {
return "--" // or some other default string
}
let totalSeconds = Int(rawSeconds)
let seconds = totalSeconds % 60
let minutes = totalSeconds / 60
let timeFormatString = String(format: "%02d:%02d", minutes, seconds)
return timeFormatString
}
Double value cannot be converted to Int64 because it is either infinite or NaN
Try to follow the error message...
"Double value cannot be converted to Int64 because it is either infinite or NaN" - and you say it's on the let seekTime = CMTime(value: Int64(val), timescale: 1)
line...
So... since that line is using Int64(val)
it's pretty clear that is where the problem is: val
is either infinite or NaN.
So... val
is being set to let val = Float64(sender.value) * totalsecs
, and totalsecs
is set by the duration let totalsecs = CMTimeGetSeconds(duration)
...
And... you say duration
is NaN.
Find out why duration
is NaN, and you have your answer.
Why does Int(Float(Int.max)) give me an error?
There aren't enough bits in the mantissa of a Double
or Float
to accurately represent 19
significant digits, so you are getting a rounded result.
If you print the Float
using String(format:)
you can see a more accurate representation of the value of the Float
:
let a = Int.max
print(a) // 9223372036854775807
let b = Float(a)
print(String(format: "%.1f", b)) // 9223372036854775808.0
So the value represented by the Float
is 1
larger than Int.max
.
Many values will be converted to the same Float
value. The question becomes, how much would you have to reduce Int.max
before it results in a different Double
or Float
value.
Starting with Double
:
var y = Int.max
while Double(y) == Double(Int.max) {
y -= 1
}
print(Int.max - y) // 512
So with Double
, the last 512
Int
s all convert to the same Double
.
Float
has fewer bits to represent the value, so there are more values that all map to the same Float
. Switching to - 1000
so that it runs in reasonable time:
var y = Int.max
while Float(y) == Float(Int.max) {
y -= 1000
}
print(Int.max - y) // 274877907000
So, your expectation that a Float
could accurately represent a specific Int
was misplaced.
Follow up question from the comments:
If float does not have enough bits to represent Int.max, how is it
able to represent a number one larger than that?
Floating point numbers are represented as two parts: mantissa and exponent. The mantissa represents the significant digits (in binary) and the exponent represents the power of 2. As a result, a floating point number can accurately express an even power of 2 by having a mantissa of 1 with an exponent that represents the power.
Numbers that are not even powers of 2 may have a binary pattern that contains more digits than can be represented in the mantissa. This is the case for Int.max
(which is 2^63 - 1) because in binary that is 111111111111111111111111111111111111111111111111111111111111111
(63 1's). A Float
which is 32 bits cannot store a mantissa which is 63 bits, so it has to be rounded or truncated. In the case of Int.max
, rounding up by 1 results in the value1000000000000000000000000000000000000000000000000000000000000000
. Starting from the left, there is only 1 significant bit to be represented by the mantissa (the trailing 0
's come for free), so this number is a mantissa of 1
and an exponent of 64
.
See @MartinR's answer for an explanation of what Java is doing.
Convert Float to Int in Swift
You can convert Float
to Int
in Swift like this:
var myIntValue:Int = Int(myFloatValue)
println "My value is \(myIntValue)"
You can also achieve this result with @paulm's comment:
var myIntValue = Int(myFloatValue)
How to check for a Not a Number (NaN) in Swift 2
You can "force unwrap" the optional type using the !
operator:
calls! //asserts that calls is NOT nil and gives a non-optional type
However, this will result in a runtime error if it is nil
.
One option to prevent using nil
or 0 is to do what you have done and check if it's 0.
The second is option is to nil
-check
if calls != nil
The third (and most Swift-y) option is to use the if let
structure:
if let nonNilCalls = calls {
//...
}
The inside of the if
block won't run if calls
is nil
.
Note that nil
-checking and if let
will NOT protect you from dividing by 0. You will have to check for that separately.
Combining second and your method:
//calls can neither be nil nor <= 0
if calls != nil && calls > 0
Related Topics
How to Use Objective-C Enum in Swift
Using Guard with a Non-Optional Value Assignment
Add Custom Header to Collection View Swift
How to Work with Bindings When Using a View Model VS Using @Binding in the View Itself
Spritekit - Create at Random Position Without Overlapping
Get Header Data from a Request Response in Swift
Undefined Behavior, Or: Does Swift Have Sequence Points
Drawing a 3D Arc and Helix in Scenekit
iOS 11 Uirefreshcontrol with Navigationbar Largetitle and Searchcontroller Disappearing
How to Edit the Uiblureffect Intensity
How to Hide the Navigation Back Button in Swiftui
Swift: Popover Dismiss Callback
Insertion-Order Dictionary (Like Java's Linkedhashmap) in Swift
(Swift) Nstimer Stop When Scrolling
Spawning a Spritekit Node at a Random Time
How to Add a Double Tap Gesture Recognizer in Swift
Create Skscene Subclasses Programmatically, Without Size Info