Double vs. Int — Why Double can store a larger number if they’re both 64-bit? Accuracy? (BONUS: CGFloat) — Swift
A DOUBLE can store a larger number because Double uses EXPONENTS to represent the number it stores, which allows Doubles to store #s up to infinity. The INT type does NOT use EXPONENTS to represent the number it stores.
Consider the 2 lines of code below:
Now print the “i” property (of type INT) to the console & you’ll see:
Now print property “d” (of type DOUBLE) & you’ll see it prints out in the form of an EXPONENT.
The DOUBLE prints out the number it stores in the form on an exponent.
— — — — — — — — — — — — —
MEMORY
The DOUBLE & the INT both still use 64-bits of memory:
- DOUBLE — represents a 64-bit floating-point number
- INT — — — represents a 64-bit integer
— — — — — — — — — — — — —
ACCURACY / PRECISION
DOUBLE is LESS PRECISE than INT
INT is 100% PRECISE
Although a DOUBLE can store a larger #, it is also LESS ACCURANT, & this is true for large & small values. Values stored in an INT; however, are always 100% ACCURATE.
REGARDING THE SCREENSHOTS BELOW:
— THE PROPERTY i:
- stores the INT value 9223372036854775807, which is the largest value an Int( ) can store. An overflow would occur if you were to change its last # from a 7 to an 8.
— THE PROPERTY d:
- “d” is initialized w/ the same value ‘i’ was initialized with, but “d” will change & will instead store the # shown in LINE 143 (the last # changes an 8)
L141’s value printed (the INT “i”) to the console doesn’t show anything unusual nor different than the value we wanted to store in the ‘i’ property:
L142's value printed to the console results in the exponent shown below, which isn’t a 100% precise representation of value we intended to store in the “d” property:
If you were to print L143’s value to the console instead, you’ll see it is also different than L142’s:
“The precision of a floating-point value is proportional to its magnitude. The larger a value, the less precise.” — Jesse Squires
Floating-point numbers (such as Double, Float, CGFloat, etc.) will not always return 100% accurate results (due to issues caused by rounding) before and/or after arithmetic operations are applied to it.
— — — — — — — — — — — — —
BONUS — CGFLOAT:
CGFloat, like Double, can represent a floating-point number up to infinity. CGFloat usually holds 64-bits to store data, but it will use 32-bits if the type of device / platform / architecture running the code warrants it, as shown in the screenshot below.
Swift 5.5 allows CGFloats & Doubles to be used interchangably (ie. You may now multiply a CGFloat by a Double, etc).
Below, we use CGFloat( ). Notice the Double( ) & the CGFloat( ) printed the same representation to the console. These printed values would have differed if I had compiled the code from a 32-bit architecture.
FOOD FOR THOUGHT — ACCURACY / PRECISION:
Although both printed the same value, only the Double was issued a warning, but this does not mean the CGFloat’s value is more precise. Double is a native Swift type & CGFloat is not. I believe the compiler may not know enough about CGFloat, resulting in CGFloat not receiving the warning.
A CGFloat will not always be 100% accurate before and / or after arithmetic operations are applied to it (due to issues caused by rounding), but sometimes it will. Examples of such operations include — addition, multiplication, converting a CGFloat( ) to a Float( ), etc.
— — — — — — — — — — — — —
REFERENCES:
- https://github.com/apple/swift-evolution/blob/main/proposals/0307-allow-interchangeable-use-of-double-cgfloat-types.md
- https://developer.apple.com/documentation/coregraphics/cgfloat
- https://github.com/apple/swift/blob/11246be177a40d2affc8efa18a8d9e2abf23c8cc/stdlib/public/Darwin/CoreGraphics/CGFloat.swift.gyb
- https://github.com/apple/swift-corelibs-foundation/blob/ee856f110177289af602c4040a996507f7d1b3ce/Sources/Foundation/CGFloat.swift#L11
— — — — — — — — — — — — —
RECOURCES:
- https://hampuswessman.se/2021/01/floating-point-basics/
- https://www.h-schmidt.net/FloatConverter/IEEE754.html
- https://www.jessesquires.com/blog/2017/10/01/floating-point-swift-ulp-and-epsilon/
- https://en.wikipedia.org/wiki/IEEE_754
- http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
- https://floating-point-gui.de
- https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html
- https://stackoverflow.com/questions/1264924/whats-the-difference-between-using-cgfloat-and-float
- https://en.wikipedia.org/wiki/Unit_in_the_last_place#Definition
- https://fabiensanglard.net/floating_point_visually_explained/
- https://stackoverflow.com/questions/10334688/how-dangerous-is-it-to-compare-floating-point-values
— — — — — — — — — — — — —
And many thanks to Jimmy Andersson, a friend who has been helpful throughout the past years as the Swift ecosystem has continued to grow.
Buy his recent work online or in bookstores worldwide: