Giter Site home page Giter Site logo

flight-school / guide-to-swift-numbers-sample-code Goto Github PK

View Code? Open in Web Editor NEW
95.0 4.0 6.0 97 KB

Xcode Playground Sample Code for the Flight School Guide to Swift Numbers

Home Page: https://flight.school/books/numbers

License: MIT License

Swift 100.00%
swift numbers floating-point numberformatter measurementformatter money currency

guide-to-swift-numbers-sample-code's Introduction

Flight School Guide to Swift Codable Cover

Guide to Swift Numbers Sample Code

Build Status License Swift Version

This repository contains sample code used in the Flight School Guide to Swift Numbers.


Chapter 1

Chapter 1 is a conceptual deep-dive into how numbers work on computers in general and in Swift specifically.

Floating Point Approximates

You know how floating-point arithmetic sometimes produces unexpected results, like 0.1 + 0.2 != 0.3? (If not, go ahead and read the first chapter for free!)

This sample code implements an "approximately equals" operator (==~) for floating-point number types.

0.1 + 0.2 == 0.3 // false
0.1 + 0.2 ==~ 0.3 // true

(0.1 + 0.2).isApproximatelyEqual(to: 0.3, within: .ulpOfOne) // true

Floating Point Environment

Normally, you can't tell the difference between nan and signalingNaN. That's because Swift doesn't expose the floating-point environment in its standard library.

We can still access it from Darwin, though. And that's what this playground demonstrates:

do {
    try detectingFloatingPointErrors(flags: .invalid) {
        Double.signalingNaN + 1
    }
} catch {
    print("Error: \(error)")
}

Chapter 2

Chapter 2 is all about number formatting. The sample code in this chapter offers a comprehensive survey of the various formatting styles of NumberFormatter, and how they work in different locales.

Cardinal Numbers

let formatter = NumberFormatter()
formatter.string(for: 4) // 4

formatter.numberStyle = .spellOut
formatter.string(for: 4) // four

Ordinal Numbers

let formatter = NumberFormatter()
formatter.numberStyle = .ordinal
formatter.string(for: 1) // 1st

Decimal Numbers

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.string(for: 1234567.89) 1,234,567.89

Significant Digits

let formatter = NumberFormatter()
formatter.usesSignificantDigits = true

formatter.maximumSignificantDigits = 2

formatter.string(from: 123) // 120
formatter.string(from: 123456) // 120000
formatter.string(from: 123.456) // 120
formatter.string(from: 1.230000) // 1.2
formatter.string(from: 0.00123) // 0.0012

Integer and Fraction Digits

let formatter = NumberFormatter()
formatter.usesSignificantDigits = false // default

formatter.minimumIntegerDigits = 4
formatter.minimumFractionDigits = 2

formatter.string(from: 123) // 0123.00
formatter.string(from: 123456) // 123456.00
formatter.string(from: 123.456) // 0123.46
formatter.string(from: 1.230000) // 0001.23
formatter.string(from: 0.00123) // 0000.00

Rounding Modes

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 1

let numbers = [1.2, 1.22, 1.25, 1.27, -1.25]
let modes: [NumberFormatter.RoundingMode] = [.ceiling, .floor, .up, .down, .halfUp, .halfDown, .halfEven]

for mode in modes {
    formatter.roundingMode = mode

    for number in numbers {
        formatter.string(for: number)
    }
}

Scientific Notation

let formatter = NumberFormatter()
formatter.numberStyle = .scientific
formatter.string(for: 12345.6789) // 1.23456789E4

Percentages

let formatter = NumberFormatter()
formatter.numberStyle = .percent
formatter.string(for: 0.12) // 12%

Currencies

let formatter = NumberFormatter()

let identifiers =
    ["en-US", "en-GB", "de-DE", "ja-JP"]
let styles: [NumberFormatter.Style] =
    [.currency, .currencyAccounting, .currencyISOCode, .currencyPlural]

for style in styles {
    formatter.numberStyle = style
    for identifier in identifiers {
        formatter.locale = Locale(identifier: identifier)
        formatter.string(for: 1234.567)
    }
}

Custom Formats

let formatter = NumberFormatter()
formatter.numberStyle = .decimal

// Format with thousands and decimal separator
// that rounds to the nearest five tenths
formatter.format = "#,##0.5"

formatter.locale = Locale(identifier: "en-US")
formatter.string(for: 1234.567) // 1,234.5

formatter.locale = Locale(identifier: "fr-FR")
formatter.string(for: 1234.567) // 1 234,5

Chapter 3

Chapter 3 shows the correct way to represent and work with money in code.

Money

let prices: [Money<USD>] = [2.19, 5.39, 20.99, 2.99, 1.99, 1.99, 0.99]
let subtotal = prices.reduce(0.00, +)
let tax = 0.08 * subtotal
let total = subtotal + tax // $39.45

Currency Converter

let EURtoUSD = CurrencyPair<EUR, USD>(rate: 1.17) // as of June 1st, 2018

let euroAmount: Money<EUR> = 123.45
let dollarAmount = EURtoUSD.convert(euroAmount) // $144.44

Chapter 4

Chapter 4 covers Foundation's units and measurements APIs.

Natural Scale

let lengthOfRoom = Measurement<UnitLength>(value: 8, unit: .meters)
let distanceToAirport = Measurement<UnitLength>(value: 16, unit: .kilometers)

let formatter = MeasurementFormatter()
formatter.unitOptions = .naturalScale
formatter.string(from: lengthOfRoom) // 26.247 ft
formatter.string(from: distanceToAirport) // 9.942 mi

Provided Units

let ingotMass = Measurement<UnitMass>(value: 400, unit: .ouncesTroy)

let formatter = MeasurementFormatter()
formatter.unitOptions = .providedUnit
formatter.string(from: ingotMass) // 400 oz t

Configuring Precision

let barometerReading = Measurement<UnitPressure>(value: 29.9, unit: .inchesOfMercury)
let pressureInMillibars = barometerReading.converted(to: .millibars)

let formatter = MeasurementFormatter()
formatter.unitOptions = .providedUnit
formatter.numberFormatter.usesSignificantDigits = true
formatter.numberFormatter.maximumSignificantDigits = 3
formatter.string(from: pressureInMillibars) // 1,010 mbar

Temperature Formatting

let temperatureInF = Measurement<UnitTemperature>(value: 72, unit: .fahrenheit)
let temperatureInC = Measurement<UnitTemperature>(value: 20.5, unit: .celsius)

let formatter = MeasurementFormatter()
formatter.locale = Locale(identifier: "en-US")
formatter.string(from: temperatureInF) // 72°F
formatter.string(from: temperatureInC) // 68.9°F

formatter.locale = Locale(identifier: "fr-FR")
formatter.string(from: temperatureInF) // 22,222 °C
formatter.string(from: temperatureInC) // 20,5 °C

formatter.unitOptions = .temperatureWithoutUnit

formatter.locale = Locale(identifier: "en-US")
formatter.string(from: temperatureInF) // 72°
formatter.string(from: temperatureInC) // 20.5° (!)

formatter.locale = Locale(identifier: "fr-FR")
formatter.string(from: temperatureInF) // 72° (!)
formatter.string(from: temperatureInC) // 20,5°

Units Interoperability

let loggedFlyingTime =
    Measurement<UnitDuration>(value: 220, unit: .hours)

let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.day]
formatter.unitsStyle = .full
formatter.includesApproximationPhrase = true
formatter.string(from: loggedFlyingTime) // About 9 days

Chapter 5

Chapter 5 extends what we learned about units in the previous chapter to transform Xcode Playgrounds into an interactive physical calculator.

Agricultural Flight Planner

let takeoffWeight = (
    emptyPlaneWeight +
    payloadWeight +
    fuelWeight +
    pilotWeight
).converted(to: .pounds)

let canTakeOff = takeoffWeight < maximumTakeoffWeight // ???

License

MIT

About Flight School

Flight School is a book series for advanced Swift developers that explores essential topics in iOS and macOS development through concise, focused guides.

If you'd like to get in touch, feel free to message us on Twitter or email us at [email protected].

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.