Swift Измерение класс · точность преобразования угла - PullRequest
0 голосов
/ 03 июля 2018

Swift 4.2 Xcode 10β2

Фон

Я работаю над созданием API, связанного с астрономией, для обработки математики в приложении, над которым я работаю. Предполагалось использовать класс Measurement для обработки ввода и вывода углов и расстояний. Таким образом, пользователь может вводить данные, используя свои предпочтительные единицы (например, градусы или радианы, мили или километры или любую комбинацию) и получать выходные данные в тех же единицах.

Это, казалось, работало очень хорошо, пока я не проверил результаты. При относительно простом расчете, таком как расстояние от центра Земли на данной широте, я получал ошибки порядка двух километров.

Это заняло пару часов (потому что я предполагал, что в вычислениях были ошибки округления), но я в конечном итоге отследил проблему до самого класса Measurment. Коэффициент преобразования между градусами и радианами является неточным. Это должно быть 180.0 / Double.pi (57,29577951308232 ...), но 57,9528.

Пример кода

print(UnitAngle.radians.converter.baseUnitValue(fromValue: 1.0))  // Inaccurate.
print(180.0 / Double.pi)                                          // Accurate.

Вопросы

Итак, два (нормально три) вопроса:

  1. Это ошибка? Это должно быть ошибка. Это слишком неточно.
  2. Можно ли установить коэффициент преобразования на другое значение (или подкласс Measurement для достижения того же).
  3. Должен ли я свернуть свой собственный класс измерений или просто отказаться от идеи преобразования единиц и придерживаться внутренних единиц СИ? (Было бы грустно, потому что, в противном случае, это именно то, что я хочу.)

1 Ответ

0 голосов
/ 03 июля 2018
import Foundation

print(UnitAngle.radians.converter.baseUnitValue(fromValue: 1.0)) // 57.2958
print(180.0 / .pi) // 57.2957795130823
print(UnitAngle.radians.converter.baseUnitValue(fromValue: .pi)) // 180.00006436155007

Это ошибка? Это должно быть ошибка. Это слишком неточно.

Я бы сказал, да. Все Measurement API принимают Double аргументы и возвращают Double значений. Это большое отклонение нельзя просто объяснить неточности с плавающей точкой, и делает результат бесполезным для серьезной работы с тригонометрическими функциями.

Интересно, что результат верен на Ubuntu Linux (где с открытым исходным кодом реализация из используется Units.swift ):

Welcome to Swift version 4.2-dev (LLVM ec4d8ae334, Clang 5a454fa3d6, Swift 0ca361f487). Type :help for assistance.
  1> import Foundation

  2> print(UnitAngle.radians.converter.baseUnitValue(fromValue: 1.0))
57.29577951308232

  3> print(180.0 / .pi)
57.29577951308232

  4> print(UnitAngle.radians.converter.baseUnitValue(fromValue: .pi))
180.0

Можно ли установить коэффициент преобразования на другое значение (или на измерение подкласса для достижения того же самого).

Аналогично Swift - преобразование измерений (в :) мили в футы дает неверный результат , вы можете определите свой собственный блок:

extension UnitAngle {
    static let preciseRadians = UnitAngle(symbol: "rad",
                        converter: UnitConverterLinear(coefficient: 180.0 / .pi))
}

print(UnitAngle.preciseRadians.converter.baseUnitValue(fromValue: 1.0)) // 57.2957795130823
print(UnitAngle.preciseRadians.converter.baseUnitValue(fromValue: .pi)) // 180.0

Должен ли я свернуть свой собственный класс измерений или просто отказаться от идеи преобразования единиц и придерживаться внутренних единиц СИ?

Это вам решать:)

...