快速假设三angular函数的计算

是否有可能在Swift for iOS中更改设置,属性等,以便它假定三angular计算的度数而不是弧度?

例如sin(90)将被评估为1

我有:

 let pi = 3.14 var r2d = 180.0/pi var d2r = pi/180 

…但是一些长三angular方程的转换正在变得非常重要。

正如在其他答案中已经说过的那样,标准库中没有以度为参数的三angular函数。

如果你定义你自己的函数,那么你可以使用__sinpi()__cospi()等等,而不是乘以π:

 // Swift 2: func sin(degrees degrees: Double) -> Double { return __sinpi(degrees/180.0) } // Swift 3: func sin(degrees: Double) -> Double { return __sinpi(degrees/180.0) } 

__sinpi手册页 (添加重点):

__sinpi()函数返回pi的x倍(以弧度为单位)的正弦值。 这可以比sin(M_PI * x) 更准确地计算出来,因为它可以隐含地使用尽可能多的pi比特来提供全面的结果,而不是M_PI被限制的53比特。 对于大的x也可能更有效率,因为涉及的参数减less要简单得多。

__sinpi()和相关函数是非标准的,但在iOS 7 / OS X 10.9及更高版本中可用。

例:

 sin(degrees: 180.0) // 0 

给出了一个确切的结果,相比之下:

 sin(180.0 * M_PI/180.0) // 1.224646799147353e-16 

只是为了好玩:这就是你如何为所有浮点types定义基于度数的正弦函数,包括带有函数重载的CGFloat (现在更新为Swift 3):

 func sin(degrees: Double) -> Double { return __sinpi(degrees/180.0) } func sin(degrees: Float) -> Float { return __sinpif(degrees/180.0) } func sin(degrees: CGFloat) -> CGFloat { return CGFloat(sin(degrees: degrees.native)) } 

在最后一个版本中,编译器会根据degrees.native的实际types自动进行推断,以便在32位和64位平台上正常工作。

添加一个扩展名来清晰地标识值的types将是处理这样一个事情的适当方式:

 import Darwin // needed to get M_PI extension Double { public var degrees: Double { return self * M_PI / 180 } public var ㎭: Double { return self * 180 / M_PI } } 

把它们放到操场上,看看你如何得到预期的结果:

 sin(90.degrees) --> 1.0 1.㎭ --> 57.2957795130823 1.㎭.degrees --> 1.0 (M_PI / 3).㎭ --> 60.0 

您可以定义返回度数值的全局函数。 只需将该函数放在任何类之外的swift文件中即可。

 func sind(degrees: Double) -> Double { return sin(degrees * M_PI / 180.0) } 

所以你可以在你的项目的任何地方使用:

 sind(90) // Returns 1 

这运行在一个操场上,并提供了度/弧度单位types安全的实现。 types定义可以从Swift evolution邮件列表中免费获取,并附带一些小的语法修复。 我写了一些trig函数。 其余的是我所展示的直接延续。

 import Cocoa //MARK:- AngleType protocol AngleType: FloatLiteralConvertible, IntegerLiteralConvertible { var value: Double { get set } init(_ value: Double) init(_ value: Int) init<T: IntegerType>(integerLiteral value: T) init<T: FloatingPointType>(floatLiteral value: T) } // Implement FloatLiteralConvertible and IntegerLiteralConvertible extension AngleType { init<T: IntegerType>(integerLiteral value: T) { self.init(value) } init<T: IntegerType>(_ value: T) { self.init(integerLiteral: value) } init<T: FloatingPointType>(floatLiteral value: T) { self.init(value) } init<T: FloatingPointType>(_ value: T) { self.init(floatLiteral: value) } } //MARK:- Degree struct Degree: AngleType { typealias FloatLiteralType = Double typealias IntegerLiteralType = Int var value: Double init(_ value: Double) { self.value = value } init(_ value: Int) { self.value = Double(value) } } protocol DegreeConvertible { init(degreeLiteral value: Degree) } extension Degree: CustomStringConvertible, CustomDebugStringConvertible { var description: String { return self.value.description } var debugDescription: String { return "\(self.value.description)°" } } extension Degree: RadianConvertible { init(radianLiteral value: Radian) { self.value = Double(radianLiteral:value) * 180.0 / M_PI } init(_ value: Radian) { self.init(radianLiteral: value) } } //MARK:- Radian struct Radian: AngleType { typealias FloatLiteralType = Double typealias IntegerLiteralType = Int var value: Double init(_ value: Double) { self.value = value } init(_ value: Int) { self.value = Double(value) } } protocol RadianConvertible { init(radianLiteral value: Radian) } extension Radian: CustomStringConvertible, CustomDebugStringConvertible { var description: String { return self.value.description } var debugDescription: String { return "\(self.value.description)㎭" } } extension Radian: DegreeConvertible { init(degreeLiteral value: Degree) { self.value = Double(degreeLiteral: value) * M_PI / 180.0 } init(_ value: Degree) { self.init(degreeLiteral: value) } } //MARK:- Adding Conformance To Built In Types extension FloatLiteralType: DegreeConvertible, RadianConvertible { init(degreeLiteral degree: Degree) { self = degree.value } init(radianLiteral radian: Radian) { self = radian.value } } extension CGFloat: DegreeConvertible, RadianConvertible { init(degreeLiteral degree: Degree) { self.init(degree.value) } init(radianLiteral radian: Radian) { self.init(radian.value) } init(_ degree: Degree) { self.init(degreeLiteral: degree) } init(_ radian: Radian) { self.init(radianLiteral: radian) } } func sin(value: Radian) -> Double { return sin(Double(value.value)) } func asin(value: Double) -> Radian { return Radian(Double(asin(value))) } func cos(value: Radian) -> Double{ return cos(Double(value.value)) } func acos(value: Double) -> Radian { return Radian(Double(acos(value))) } func sin(value: Degree) -> Double{ return sin(Radian(value)) } func asin(value: Double) -> Degree { return Degree(Double(asin(value))) } func cos(value: Degree) -> Double{ return cos(Radian(value)) } func acos(value: Double) -> Degree { return Degree(Double(acos(value))) } let d180: Degree = Degree(180.0) let r180: Radian = Radian(degreeLiteral: d180) let d0 = Degree(0.0) let r0 = Radian(d0) let dsin180 = sin(d180) let rsin180 = sin(r180) let dcos180 = cos(d180) let rcos180 = cos(r180) let dsin0 = sin(d0) let rsin0 = sin(r0) let dcos0 = cos(d0) let rcos0 = cos(r0) let adsin180: Degree = asin(dsin180) let adcos180: Degree = acos(dcos180) 

没有设置或属性来改变内置的三angular函数。 如果你想简化expression式,或者定义你自己的sindegcosdeg等,你应该严格按照弧度工作。

有一个内置的M_PI ,你应该使用,而不是定义自己的pi常量。

另外,罪90˚是1,而不是0。

我不完全确定为什么要重载默认的全局方法,但是如果必须的话,您可以提供一个备用的方法签名:

 func sin(#degrees: Double) -> Double { // Require a parameter name for method call let radians: Double = degrees * (M_PI / 180) // Convert to rad return sin(radians) // Return result of default method call with automatic conversion } sin(degrees: 90) // 1.0 sin(degrees: 180) // 0.0 

然而,这实际上是一种奇怪的做法,以相似的方式显式定义自己的方法(这就是他们所要做的)会更有意义:

 func sinFromDegrees(degrees: Double) -> Double { let radians: Double = degrees * (M_PI / 180) return sin(radians) } sinFromDegrees(90) // 1.0 sinFromDegrees(180) // 0.0 

看着我使用触发很多。 我发现最好的方法是在class ViewController之外定义一些函数。

如果你在任何一个.swift文件中定义它们,就在imports下面,并且在class ViewController:UIViewController { }上方,那么你可以在整个项目中调用它们。

所以对于sin函数,我把它命名为sindeg()代表“sin度”。

 func sindeg(degrees: Double) -> Double { return sin(degrees * M_PI / 180.0) } 

所以这需要你的学位数字转换它,解决它并返回度。 所以你只需要inputsindeg(45.5) ,结果就是0.71325045.

这是其他的:

 func cosdeg(degrees: Double) -> Double { return cos(degrees * M_PI / 180.0) } func tandeg(degrees: Double) -> Double { return tan(degrees * M_PI / 180.0) } 

arcTan在这里是非常相似的,唯一的区别是返回公式

  func atanDegree(degrees: Double) -> Double { return atan(degrees) * 180 / M_PI } 

这一个只是将弧度值转换成度。 采用弧度,转换,返回度数。

 func Convert(radians: Double) -> Double { return radians * 180.0 / M_PI }