Skip to content

Commit 777750d

Browse files
authored
Merge pull request #23140 from stephentyrone/mafs
Math functions for Swift
2 parents 0c8920e + bcc7e2c commit 777750d

18 files changed

+1208
-225
lines changed

stdlib/public/Darwin/CoreGraphics/CGFloat.swift.gyb

Lines changed: 98 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -513,18 +513,111 @@ public func %=(lhs: inout CGFloat, rhs: CGFloat) {
513513
// tgmath
514514
//===----------------------------------------------------------------------===//
515515

516+
%from SwiftMathFunctions import *
517+
extension CGFloat: Real {
518+
% for func in ElementaryFunctions + RealFunctions:
519+
520+
@_alwaysEmitIntoClient
521+
public static func ${func.decl("CGFloat")} {
522+
return CGFloat(NativeType.${func.swiftName}(${func.params("", ".native")}))
523+
}
524+
% end
525+
526+
@_alwaysEmitIntoClient
527+
public static func pow(_ x: CGFloat, _ y: CGFloat) -> CGFloat {
528+
return CGFloat(NativeType.pow(x.native, y.native))
529+
}
530+
531+
@_alwaysEmitIntoClient
532+
public static func pow(_ x: CGFloat, _ n: Int) -> CGFloat {
533+
return CGFloat(NativeType.pow(x.native, n))
534+
}
535+
536+
@_alwaysEmitIntoClient
537+
public static func root(_ x: CGFloat, _ n: Int) -> CGFloat {
538+
return CGFloat(NativeType.root(x.native, n))
539+
}
540+
541+
@_alwaysEmitIntoClient
542+
public static func atan2(y: CGFloat, x: CGFloat) -> CGFloat {
543+
return CGFloat(NativeType.atan2(y: y.native, x: x.native))
544+
}
545+
546+
#if !os(Windows)
547+
@_alwaysEmitIntoClient
548+
public static func logGamma(_ x: CGFloat) -> CGFloat {
549+
return CGFloat(NativeType.logGamma(x.native))
550+
}
551+
#endif
552+
}
553+
554+
@available(swift, deprecated: 5.1, message: "Use `root(x, 3)`.")
555+
@_transparent
556+
public func cbrt(_ x: CGFloat) -> CGFloat {
557+
return CGFloat.root(x, 3)
558+
}
559+
560+
@available(swift, deprecated: 5.1, message: "Use CGFloat.minimum( ) or Swift.min( )")
561+
@_transparent
562+
public func fmin(_ x: CGFloat, _ y: CGFloat) -> CGFloat {
563+
return .minimum(x, y)
564+
}
565+
566+
@available(swift, deprecated: 5.1, message: "Use CGFloat.maximum( ) or Swift.max( )")
567+
@_transparent
568+
public func fmax(_ x: CGFloat, _ y: CGFloat) -> CGFloat {
569+
return .maximum(x, y)
570+
}
571+
572+
#if !os(Windows)
573+
@available(swift, deprecated: 5.1, message: "Use (logGamma(x), signGamma(x)).")
574+
@_transparent
575+
public func lgamma(_ x: CGFloat) -> (CGFloat, Int) {
576+
return (CGFloat.logGamma(x), CGFloat.signGamma(x) == .plus ? 1 : -1)
577+
}
578+
#endif
579+
580+
@available(swift, deprecated: 5.1, message: "Use `x.exponent` or `floor(log2(x))`.")
581+
@_transparent
582+
public func logb(_ x: CGFloat) -> CGFloat {
583+
return CGFloat.log2(x).rounded(.down)
584+
}
585+
586+
@available(swift, deprecated: 5.1, message: "Swift does not model dynamic rounding modes, use x.rounded(.toNearestOrEven).")
587+
@_transparent
588+
public func nearbyint(_ x: CGFloat) -> CGFloat {
589+
return x.rounded(.toNearestOrEven)
590+
}
591+
592+
@available(swift, deprecated: 5.1, message: "Use the .nextUp or .nextDown property.")
593+
@_transparent
594+
public func nextafter(_ x: CGFloat, _ y: CGFloat) -> CGFloat {
595+
return y > x ? x.nextUp : (y < x ? x.nextDown : y)
596+
}
597+
598+
@available(swift, deprecated: 5.1, message: "Swift does not model dynamic rounding modes, use x.rounded(.toNearestOrEven).")
599+
@_transparent
600+
public func rint(_ x: CGFloat) -> CGFloat {
601+
return x.rounded(.toNearestOrEven)
602+
}
603+
604+
@available(swift, deprecated: 5.1, message: "Use `gamma(x)`.")
605+
@_transparent
606+
public func tgamma(_ x: CGFloat) -> CGFloat {
607+
return CGFloat.gamma(x)
608+
}
609+
516610
%{
517611
UnaryFunctions = [
518612
'acos', 'asin', 'atan', 'cos', 'sin', 'tan',
519613
'acosh', 'asinh', 'atanh', 'cosh', 'sinh', 'tanh',
520614
'exp', 'exp2', 'expm1',
521-
'log', 'log10', 'log1p', 'log2', 'logb',
522-
'cbrt', 'erf', 'erfc', 'tgamma',
523-
'nearbyint', 'rint'
615+
'log', 'log10', 'log1p', 'log2',
616+
'erf', 'erfc',
524617
]
525618

526619
BinaryFunctions = [
527-
'atan2', 'hypot', 'pow', 'copysign', 'nextafter', 'fdim', 'fmax', 'fmin'
620+
'atan2', 'hypot', 'pow', 'copysign', 'fdim'
528621
]
529622
}%
530623

@@ -571,18 +664,12 @@ public func ldexp(_ x: CGFloat, _ n: Int) -> CGFloat {
571664
return CGFloat(ldexp(x.native, n))
572665
}
573666

574-
@available(swift, deprecated: 4.2, message: "use the exponent property.")
667+
@available(swift, deprecated: 4.2, obsoleted: 5.1, message: "use the exponent property.")
575668
@_transparent
576669
public func ilogb(_ x: CGFloat) -> Int {
577670
return Int(x.exponent)
578671
}
579672

580-
@_transparent
581-
public func lgamma(_ x: CGFloat) -> (CGFloat, Int) {
582-
let (value, sign) = lgamma(x.native)
583-
return (CGFloat(value), sign)
584-
}
585-
586673
@_transparent
587674
public func remquo(_ x: CGFloat, _ y: CGFloat) -> (CGFloat, Int) {
588675
let (rem, quo) = remquo(x.native, y.native)

stdlib/public/Platform/tgmath.swift.gyb

Lines changed: 106 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -14,11 +14,12 @@ import SwiftShims
1414

1515
// Generic functions implementable directly on FloatingPoint.
1616
@_transparent
17-
@available(swift, deprecated: 4.2, renamed: "abs")
17+
@available(swift, deprecated: 4.2, obsoleted: 5.1, renamed: "Swift.abs")
1818
public func fabs<T: FloatingPoint>(_ x: T) -> T {
1919
return x.magnitude
2020
}
2121

22+
@available(swift, obsoleted: 5.1, message: "Use Swift.sqrt(x) or x.squareRoot().")
2223
@_transparent
2324
public func sqrt<T: FloatingPoint>(_ x: T) -> T {
2425
return x.squareRoot()
@@ -112,7 +113,7 @@ public func isnan<T: FloatingPoint>(_ value: T) -> Bool { fatalError() }
112113
@available(*, unavailable, message: "use the sign property.")
113114
public func signbit<T: FloatingPoint>(_ value: T) -> Int { fatalError() }
114115

115-
@available(swift, deprecated: 4.2, message: "use the exponent property.")
116+
@available(swift, deprecated: 4.2, obsoleted: 5.1, message: "use the exponent property.")
116117
public func ilogb<T: BinaryFloatingPoint>(_ x: T) -> Int {
117118
return Int(x.exponent)
118119
}
@@ -155,44 +156,20 @@ UnaryFunctions = [
155156
'acos', 'asin', 'atan', 'tan',
156157
'acosh', 'asinh', 'atanh', 'cosh', 'sinh', 'tanh',
157158
'expm1',
158-
'log1p', 'logb',
159-
'cbrt', 'erf', 'erfc', 'tgamma',
159+
'log1p',
160+
'erf', 'erfc',
160161
]
161162

162163
# These functions have a corresponding LLVM intrinsic
163-
# We call this intrinsic via the Builtin method so keep this list in
164-
# sync with core/BuiltinMath.swift.gyb
165164
UnaryIntrinsicFunctions = [
166-
'cos', 'sin',
167-
'exp', 'exp2',
168-
'log', 'log10', 'log2',
169-
'nearbyint', 'rint',
165+
'cos', 'sin', 'exp', 'exp2', 'log', 'log10', 'log2', 'nearbyint', 'rint'
170166
]
171167

172168
# (T, T) -> T
173169
BinaryFunctions = [
174-
'atan2', 'hypot', 'pow',
175-
'copysign', 'nextafter', 'fdim', 'fmax', 'fmin'
170+
'atan2', 'hypot', 'fdim', 'copysign'
176171
]
177172

178-
# These functions have special implementations.
179-
OtherFunctions = [
180-
'scalbn', 'lgamma', 'remquo', 'nan', 'jn', 'yn'
181-
]
182-
183-
# These functions are imported correctly as-is.
184-
OkayFunctions = ['j0', 'j1', 'y0', 'y1']
185-
186-
# These functions are not supported for various reasons.
187-
UnhandledFunctions = [
188-
'math_errhandling', 'scalbln',
189-
'lrint', 'lround', 'llrint', 'llround', 'nexttoward',
190-
'isgreater', 'isgreaterequal', 'isless', 'islessequal',
191-
'islessgreater', 'isunordered', '__exp10',
192-
'__sincos', '__cospi', '__sinpi', '__tanpi', '__sincospi'
193-
]
194-
195-
196173
def AllFloatTypes():
197174
for bits in allFloatBits:
198175
yield floatName(bits), cFloatName(bits), cFuncSuffix(bits)
@@ -226,50 +203,74 @@ def TypedBinaryFunctions():
226203
% end
227204
@_transparent
228205
public func ${ufunc}(_ x: ${T}) -> ${T} {
229-
return ${T}(${ufunc}${f}(${CT}(x)))
206+
return ${T}.${ufunc}(x)
230207
}
231208
% if T == 'Float80':
232209
#endif
233210
% end
234211

235212
% end
213+
@available(swift, deprecated: 5.1, message: "Use `root(x, 3)`.")
214+
@_transparent
215+
public func cbrt(_ x: Float) -> Float {
216+
return Float.root(x, 3)
217+
}
218+
219+
@available(swift, deprecated: 5.1, message: "Use `x.exponent` or `floor(log2(x))`.")
220+
@_transparent
221+
public func logb(_ x: Float) -> Float {
222+
return Float.log2(x).rounded(.down)
223+
}
224+
225+
@available(swift, deprecated: 5.1, message: "Use `gamma(x)`.")
226+
@_transparent
227+
public func tgamma(_ x: Float) -> Float {
228+
return Float.gamma(x)
229+
}
230+
231+
#if (arch(i386) || arch(x86_64)) && !os(Windows)
232+
@available(swift, deprecated: 5.1, message: "Use `root(x, 3)`.")
233+
@_transparent
234+
public func cbrt(_ x: Float80) -> Float80 {
235+
return Float80.root(x, 3)
236+
}
237+
238+
@available(swift, deprecated: 5.1, message: "Use `x.exponent` or `floor(log2(x))`.")
239+
@_transparent
240+
public func logb(_ x: Float80) -> Float80 {
241+
return Float80.log2(x).rounded(.down)
242+
}
243+
244+
@available(swift, deprecated: 5.1, message: "Use `gamma(x)`.")
245+
@_transparent
246+
public func tgamma(_ x: Float80) -> Float80 {
247+
return Float80.gamma(x)
248+
}
249+
#endif
236250

237-
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
238251
// Unary intrinsic functions
239252
// Note these have a corresponding LLVM intrinsic
240253
% for T, ufunc in TypedUnaryIntrinsicFunctions():
241254
% if T == 'Float80':
242255
#if (arch(i386) || arch(x86_64)) && !os(Windows)
243256
% end
257+
% if ufunc[-3:] != 'int':
244258
@_transparent
245259
public func ${ufunc}(_ x: ${T}) -> ${T} {
246-
return _${ufunc}(x)
260+
return ${T}.${ufunc}(x)
247261
}
248-
% if T == 'Float80':
249-
#endif
250-
% end
251-
252-
% end
253-
#else
254-
// FIXME: As of now, we cannot declare 64-bit (Double/CDouble) overlays here.
255-
// Since CoreFoundation also exports libc functions, they will conflict with
256-
// Swift overlays when building Foundation. For now, just like normal
257-
// UnaryFunctions, we define overlays only for OverlayFloatTypes.
258-
% for ufunc in UnaryIntrinsicFunctions:
259-
% for T, CT, f in OverlayFloatTypes():
260-
% if T == 'Float80':
261-
#if (arch(i386) || arch(x86_64)) && !os(Windows)
262-
% end
262+
% else:
263+
@available(swift, deprecated: 5.1, message: "Swift does not model dynamic rounding modes, use x.rounded(.toNearestOrEven) instead.")
263264
@_transparent
264265
public func ${ufunc}(_ x: ${T}) -> ${T} {
265-
return ${T}(${ufunc}${f}(${CT}(x)))
266+
return x.rounded(.toNearestOrEven)
266267
}
267-
% if T == 'Float80':
268+
% end
269+
% if T == 'Float80':
268270
#endif
269-
% end
270271
% end
272+
271273
% end
272-
#endif
273274

274275
// Binary functions
275276

@@ -287,6 +288,54 @@ public func ${bfunc}(_ lhs: ${T}, _ rhs: ${T}) -> ${T} {
287288

288289
% end
289290

291+
@_transparent
292+
public func pow(_ x: Float, _ y: Float) -> Float {
293+
return Float.pow(x, y)
294+
}
295+
296+
@available(swift, deprecated: 5.1, message: "Use the .nextUp and .nextDown properties.")
297+
@_transparent
298+
public func nextafter(_ x: Float, _ y: Float) -> Float {
299+
return y > x ? x.nextUp : (y < x ? x.nextDown : y)
300+
}
301+
302+
@available(swift, deprecated: 5.1, message: "Use Float.minimum( ) or Swift.min( )")
303+
@_transparent
304+
public func fmin(_ x: Float, _ y: Float) -> Float {
305+
return .minimum(x, y)
306+
}
307+
308+
@available(swift, deprecated: 5.1, message: "Use Float.maximum( ) or Swift.max( )")
309+
@_transparent
310+
public func fmax(_ x: Float, _ y: Float) -> Float {
311+
return .maximum(x, y)
312+
}
313+
314+
#if (arch(i386) || arch(x86_64)) && !os(Windows)
315+
@_transparent
316+
public func pow(_ x: Float80, _ y: Float80) -> Float80 {
317+
return Float80.pow(x, y)
318+
}
319+
320+
@available(swift, deprecated: 5.1, message: "Use the .nextUp and .nextDown properties.")
321+
@_transparent
322+
public func nextafter(_ x: Float80, _ y: Float80) -> Float80 {
323+
return y > x ? x.nextUp : (y < x ? x.nextDown : y)
324+
}
325+
326+
@available(swift, deprecated: 5.1, message: "Use Float80.minimum( ) or Swift.min( )")
327+
@_transparent
328+
public func fmin(_ x: Float80, _ y: Float80) -> Float80 {
329+
return Float80.minimum(x, y)
330+
}
331+
332+
@available(swift, deprecated: 5.1, message: "Use Float80.maximum( ) or Swift.max( )")
333+
@_transparent
334+
public func fmax(_ x: Float80, _ y: Float80) -> Float80 {
335+
return Float80.maximum(x, y)
336+
}
337+
#endif
338+
290339
% # This is AllFloatTypes not OverlayFloatTypes because of the tuple return.
291340
% for T, CT, f in AllFloatTypes():
292341
% if T == 'Float80':
@@ -295,11 +344,10 @@ public func ${bfunc}(_ lhs: ${T}, _ rhs: ${T}) -> ${T} {
295344
// lgamma not available on Windows, apparently?
296345
#if !os(Windows)
297346
% end
347+
@available(swift, deprecated: 5.1, message: "Use (logGamma(x), signGamma(x)).")
298348
@_transparent
299349
public func lgamma(_ x: ${T}) -> (${T}, Int) {
300-
var sign = Int32(0)
301-
let value = lgamma${f}_r(${CT}(x), &sign)
302-
return (${T}(value), Int(sign))
350+
return (${T}.logGamma(x), ${T}.signGamma(x) == .plus ? 1 : -1)
303351
}
304352
#endif
305353

@@ -326,8 +374,8 @@ public func remquo(_ x: ${T}, _ y: ${T}) -> (${T}, Int) {
326374
% if T == 'Float80':
327375
#if (arch(i386) || arch(x86_64)) && !os(Windows)
328376
% end
329-
@available(swift, deprecated: 4.2, message:
330-
"use ${T}(nan: ${T}.RawSignificand) instead.")
377+
@available(swift, deprecated: 4.2, obsoleted: 5.1, message:
378+
"use ${T}(nan: ${T}.RawSignificand).")
331379
@_transparent
332380
public func nan(_ tag: String) -> ${T} {
333381
return ${T}(nan${f}(tag))

0 commit comments

Comments
 (0)