Skip to content

Commit 07fbec5

Browse files
authored
Improve guidance for integer and floating-point numbers (#398)
- Added a mention of fixed-point math - Call out finance and other areas where neither int nor float is sufficient - Contrast integers as "counting numbers" with floating-point numbers as "measurements" - Added a mention of special values like negative zero and NaN Fixes: rdar://122436757
2 parents 995fc9f + 0f4377d commit 07fbec5

File tree

1 file changed

+98
-28
lines changed

1 file changed

+98
-28
lines changed

TSPL.docc/LanguageGuide/TheBasics.md

Lines changed: 98 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -477,13 +477,44 @@ let cat = "🐱"; print(cat)
477477
*Integers* are whole numbers with no fractional component,
478478
such as `42` and `-23`.
479479
Integers are either *signed* (positive, zero, or negative)
480-
or *unsigned* (positive or zero).
481-
482-
Swift provides signed and unsigned integers in 8, 16, 32, and 64 bit forms.
483-
These integers follow a naming convention similar to C,
484-
in that an 8-bit unsigned integer is of type `UInt8`,
480+
or *unsigned* (positive or zero),
481+
and their maximum and minimum value depends on their *size*
482+
(the number of bits used to store values).
483+
The integer types include their size and sign in their names ---
484+
for example, an 8-bit unsigned integer is of type `UInt8`,
485485
and a 32-bit signed integer is of type `Int32`.
486486
Like all types in Swift, these integer types have capitalized names.
487+
In most cases,
488+
when you don't need to specify the exact integer size,
489+
you use the `Int` type described below.
490+
491+
Integer types behave like most arithmetic you do by hand;
492+
integer math produces results without approximating.
493+
These characteristics make integers suitable for counting
494+
and other calculations that represent exact amounts ---
495+
for example,
496+
finding the longest line in a text file,
497+
applying a score multiplier in a game,
498+
or totaling prices on a receipt.
499+
500+
Although integers don't have a fractional component,
501+
you can use integers to represent quantities with fractions
502+
by counting a fractional part.
503+
For example,
504+
you can represent $1.23 by storing the number `123`
505+
in an integer that counts cents.
506+
This approach is known as *fixed-point math*
507+
because the decimal point is at a fixed position in the number.
508+
In the example above,
509+
the number `123` is understood to have a decimal point
510+
before the last two digits.
511+
512+
> Note:
513+
> For calculations in a regulated area like finance or construction,
514+
> or in a domain that has an expectation of high-precision results,
515+
> you might need a special-purpose numeric type
516+
> that implements behaviors such as rounding and truncation,
517+
> according to that area's requirements.
487518
488519
### Integer Bounds
489520

@@ -510,6 +541,12 @@ The values of these properties are of the appropriate-sized number type
510541
(such as `UInt8` in the example above)
511542
and can therefore be used in expressions alongside other values of the same type.
512543

544+
Calculations that produce out-of-bounds results,
545+
like a number larger that the `max` property,
546+
stop the program's execution instead of storing an invalid result.
547+
You can explicitly make the operation overflow instead,
548+
as described in <doc:AdvancedOperators#Overflow-Operators>.
549+
513550
### Int
514551

515552
In most cases, you don't need to pick a specific size of integer to use in your code.
@@ -543,30 +580,63 @@ which has the same size as the current platform's native word size:
543580
544581
## Floating-Point Numbers
545582

546-
*Floating-point numbers* are numbers with a fractional component,
583+
*Floating-point numbers* have a fractional component,
547584
such as `3.14159`, `0.1`, and `-273.15`.
548-
549-
Floating-point types can represent a much wider range of values than integer types,
550-
and can store numbers that are much larger or smaller than can be stored in an `Int`.
551-
Swift provides two signed floating-point number types:
552-
553-
- `Double` represents a 64-bit floating-point number.
554-
- `Float` represents a 32-bit floating-point number.
555-
556-
> Note: `Double` has a precision of at least 15 decimal digits,
557-
> whereas the precision of `Float` can be as little as 6 decimal digits.
558-
> The appropriate floating-point type to use depends on the nature and range of
559-
> values you need to work with in your code.
560-
> In situations where either type would be appropriate, `Double` is preferred.
561-
562-
<!--
563-
TODO: Explicitly mention situations where Float is appropriate,
564-
such as when optimizing for storage size of collections?
565-
-->
566-
567-
<!--
568-
TODO: mention infinity, -infinity etc.
569-
-->
585+
Swift provides a variety of floating-point types
586+
that support different sizes of numbers,
587+
just like it has different sizes of integers.
588+
If you don't need to specify an exact size, use `Double`.
589+
Otherwise,
590+
use the type that includes the needed size in its name,
591+
such as `Float16` or `Float80`.
592+
Following common terminology for floating-point math,
593+
`Float` uses 32 bits and `Double` uses 64 bits.
594+
You can also write these types as `Float32` or `Float64`.
595+
For example,
596+
graphics code often uses `Float` to match the GPU's fastest data type.
597+
Some floating-point types are supported only by certain platforms,
598+
but `Float` and `Double` are available on all platforms.
599+
600+
Floating-point numbers let you work with
601+
very small and very large numbers,
602+
but can't represent every possible value in that range.
603+
Unlike integer calculations,
604+
which always produce an exact result,
605+
floating-point math rounds results to the nearest representable number.
606+
For example,
607+
when storing the number 10,000 as a `Float`,
608+
the next largest number you can represent is 10,000.001 ----
609+
values between these two numbers round to one or the other.
610+
The space between numbers is also variable;
611+
there are larger spaces between large numbers
612+
than between small numbers.
613+
For example,
614+
the next `Float` value after 0.001 is 0.0010000002,
615+
which is smaller than the spacing after 10,000.
616+
617+
<!---
618+
var n: Float = 10_000
619+
print(n.nextUp)
620+
n = 0.001
621+
print(n.nextUp)
622+
-->
623+
624+
Floating-point numbers have values for
625+
negative zero, infinity, and negative infinity,
626+
which represent overflow and underflow in calculations.
627+
They also have include not-a-number (NaN) values
628+
to represent an invalid or undefined result,
629+
such as dividing zero by zero.
630+
This behavior is different from integers,
631+
which stop the program if they can't represent the result.
632+
633+
If you need the same spacing between all possible values,
634+
or if the calculations you're doing
635+
require exact results
636+
and don't call for the special values listed above,
637+
a floating-point number might not be the right data type.
638+
Consider using fixed-point numbers instead,
639+
as described in <doc:TheBasics#Integers>.
570640

571641
## Type Safety and Type Inference
572642

0 commit comments

Comments
 (0)