Skip to content

SR-11766: Fix coefficients for UnitVolume #2561

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 7, 2019
Merged

SR-11766: Fix coefficients for UnitVolume #2561

merged 3 commits into from
Dec 7, 2019

Conversation

ole
Copy link
Contributor

@ole ole commented Nov 12, 2019

This fixes Measurement values expressed in cubic centimeters and cubic millimeters.

I found the errors in the coefficients because I tested one of my libraries on Linux for the first time and a test was failing (see ole/Ampere#25).

I considered adding unit tests that test some conversions to Foundation, but I'm not sure how useful they would be. A test for converting a Measurement from one unit to another would essentially repeat the code that's being tested; it seems it would be almost equally likely for a bug to be in the test as it would be in the code being tested.

This fixes Measurement values expressed in cubic centimeters and cubic millimeters.

I found the errors in the coefficients because I tested one of my libraries on Linux for the first time and a test was failing (see ole/Ampere#25).

I considered adding unit tests that test some conversions to Foundation, but I'm not sure how useful they would be. A test for converting a Measurement from one unit to another would essentially repeat the code that's being tested; it seems it would be almost equally likely for a bug to be in the test as it would be in the code being tested.
@ole
Copy link
Contributor Author

ole commented Nov 12, 2019

Please let me know if you'd consider tests of this kind useful:

func testVolumeConversions() {
    let input = Measurement(value: 5, unit: UnitVolume.liters)
    let megaliters = input.converted(to: .megaliters)
    XCTAssertEqual(megaliters.value, 5e-6, "Conversion from liters to megaliters")
    let kiloliters = input.converted(to: .kiloliters)
    XCTAssertEqual(kiloliters.value, 0.005, "Conversion from liters to kiloliters")
    let deciliters = input.converted(to: .deciliters)
    XCTAssertEqual(deciliters.value, 50, "Conversion from liters to deciliters")
    ...

@spevans
Copy link
Contributor

spevans commented Nov 13, 2019

@swift-ci test

@spevans
Copy link
Contributor

spevans commented Nov 14, 2019

@ole It would definitely be good to get some tests added, currently there dont seem to be very many. If you could add a couple that would validate the constants used for conversion that would be great. Also, don't worry about the macOS test failure, thats an unrelated issue.

@spevans
Copy link
Contributor

spevans commented Nov 17, 2019

@swift-ci test macos

@ole
Copy link
Contributor Author

ole commented Nov 21, 2019

@spevans Thanks. I will add tests, but I don't know when I'll get to it. Hopefully sometime next week.

@parkera
Copy link
Contributor

parkera commented Dec 4, 2019

Thank you @ole !

@ole
Copy link
Contributor Author

ole commented Dec 5, 2019

@spevans @parkera I added some tests for UnitVolume conversions. Let me know what you think. I tried to use conversions that readers of the tests would find reasonably intuitive so that mistakes have a chance to be spotted (e.g. it's more likely that readers will know there should be 4 quarts in a gallon than that 1 gallon should be x.xx cubic inches).


func testImperialVolumeConversions() {
let cubicMiles = Measurement(value: 1, unit: UnitVolume.cubicMiles)
XCTAssertEqual(cubicMiles.converted(to: .cubicYards).value, 1760 * 1760 * 1760, accuracy: 1_000_000, "Conversion from cubicMiles to cubicYards")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Admittedly, this assertion with the insanely high accuracy threshold is kind of ridiculous. I wanted the test to be intuitive, so for people who know that 1 mile = 1760 yards, it makes sense that 1 cubic mile = 1760^3 cubic yards.

Unfortunately, that's not really the case with Measurement (even after factoring in floating-point rounding errors) because the conversion factors hardcoded by Foundation often don't use the full range offered by Double. In this instance, cubicMiles is defined like this (in Unit.swift):

static let cubicMiles           = 4.168e+12 // in liters

Whereas the "accurate" conversion factor is more like 4.16818182544058e12 (= 16093.44^3; 1 mile is 16093.44 decimeters) (I think), which leads to the huge discrepancy (in absolute terms) between the actual and expected values.

This inaccuracy is not specific to corelibs-foundation, but is the same in Darwin-Foundation. Out of interest, was it a conscious decision to limit conversion factors to x significant digits or something when the Measurement types were introduced?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as scl-foundation is concerned it just tries to match Darwin's version as closely as possible, I don't know why Foundation has such low accuracy for its conversions.

The tests should hopefully catch any accidental changes in the future so thanks for adding them, Ive kicked off a CI test for them on Linux and will merge if the tests work ok.

@spevans
Copy link
Contributor

spevans commented Dec 6, 2019

@swift-ci test linux

1 similar comment
@spevans
Copy link
Contributor

spevans commented Dec 7, 2019

@swift-ci test linux

@spevans
Copy link
Contributor

spevans commented Dec 7, 2019

@ole You'll need to add TestUnitVolume.swift into the file list in TestFoundation/CMakeLists.txt as well - this was the cause of the linux test failure.

@ole
Copy link
Contributor Author

ole commented Dec 7, 2019

@spevans Done. Sorry I missed this.

@spevans
Copy link
Contributor

spevans commented Dec 7, 2019

@swift-ci test linux

1 similar comment
@spevans
Copy link
Contributor

spevans commented Dec 7, 2019

@swift-ci test linux

@spevans spevans merged commit 914a8ae into swiftlang:master Dec 7, 2019
@ole ole deleted the unitvolume-coefficients branch December 9, 2019 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants