//===--- tgmath.swift.gyb -------------------------------------*- swift -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// import SwiftShims // Generic functions implementable directly on FloatingPoint. @_transparent @available(swift, deprecated: 4.2/*, obsoleted: 5.1*/, renamed: "abs") public func fabs(_ x: T) -> T { return x.magnitude } @_transparent public func sqrt(_ x: T) -> T { return x.squareRoot() } @_transparent public func fma(_ x: T, _ y: T, _ z: T) -> T { return z.addingProduct(x, y) } @_transparent public func remainder(_ x: T, _ y: T) -> T { return x.remainder(dividingBy: y) } @_transparent public func fmod(_ x: T, _ y: T) -> T { return x.truncatingRemainder(dividingBy: y) } @_transparent public func ceil(_ x: T) -> T { return x.rounded(.up) } @_transparent public func floor(_ x: T) -> T { return x.rounded(.down) } @_transparent public func round(_ x: T) -> T { return x.rounded() } @_transparent public func trunc(_ x: T) -> T { return x.rounded(.towardZero) } @_transparent public func scalbn(_ x: T, _ n : Int) -> T { return T(sign: .plus, exponent: T.Exponent(n), significand: x) } @_transparent public func modf(_ x: T) -> (T, T) { // inf/NaN: return canonicalized x, fractional part zero. guard x.isFinite else { return (x+0, 0) } let integral = trunc(x) let fractional = x - integral return (integral, fractional) } @_transparent public func frexp(_ x: T) -> (T, Int) { guard x.isFinite else { return (x+0, 0) } guard x != 0 else { return (x, 0) } // The C stdlib `frexp` uses a different notion of significand / exponent // than IEEE 754, so we need to adjust them by a factor of two. return (x.significand / 2, Int(x.exponent + 1)) } %for T in ['Float','Double']: @available(swift, deprecated: 4.2, renamed: "scalbn") @_transparent public func ldexp(_ x: ${T}, _ n : Int) -> ${T} { return ${T}(sign: .plus, exponent: n, significand: x) } %end // Floating-point properties that are exposed as functions in the C math // library. Mark those function names unavailable and direct users to the // properties instead. @available(*, unavailable, message: "use the floatingPointClass property.") public func fpclassify(_ value: T) -> Int { fatalError() } @available(*, unavailable, message: "use the isNormal property.") public func isnormal(_ value: T) -> Bool { fatalError() } @available(*, unavailable, message: "use the isFinite property.") public func isfinite(_ value: T) -> Bool { fatalError() } @available(*, unavailable, message: "use the isInfinite property.") public func isinf(_ value: T) -> Bool { fatalError() } @available(*, unavailable, message: "use the isNaN property.") public func isnan(_ value: T) -> Bool { fatalError() } @available(*, unavailable, message: "use the sign property.") public func signbit(_ value: T) -> Int { fatalError() } @available(swift, deprecated: 4.2/*, obsoleted: 5.1*/, message: "use the exponent property.") public func ilogb(_ x: T) -> Int { return Int(x.exponent) } %{ # Don't need 64-bit (Double/CDouble) overlays. The ordinary C imports work fine. overlayFloatBits = [32, 80] allFloatBits = [32, 64, 80] def floatName(bits): if bits == 32: return 'Float' if bits == 64: return 'Double' if bits == 80: return 'Float80' def cFloatName(bits): if bits == 32: return 'CFloat' if bits == 64: return 'CDouble' if bits == 80: return 'CLongDouble' def cFuncSuffix(bits): if bits == 32: return 'f' if bits == 64: return '' if bits == 80: return 'l' # Each of the following lists is ordered to match math.h # (T) -> T # These functions do not have a corresponding LLVM intrinsic UnaryFunctions = [ 'acos', 'asin', 'atan', 'tan', 'acosh', 'asinh', 'atanh', 'cosh', 'sinh', 'tanh', 'expm1', 'log1p', 'erf', 'erfc', ] # These functions have a corresponding LLVM intrinsic UnaryIntrinsicFunctions = [ 'cos', 'sin', 'exp', 'exp2', 'log', 'log10', 'log2', 'nearbyint', 'rint' ] def AllFloatTypes(): for bits in allFloatBits: yield floatName(bits), cFloatName(bits), cFuncSuffix(bits) def OverlayFloatTypes(): for bits in overlayFloatBits: yield floatName(bits), cFloatName(bits), cFuncSuffix(bits) def TypedUnaryFunctions(): for ufunc in UnaryFunctions: for bits in overlayFloatBits: yield floatName(bits), cFloatName(bits), cFuncSuffix(bits), ufunc def TypedUnaryIntrinsicFunctions(): for ufunc in UnaryIntrinsicFunctions: for bits in allFloatBits: yield floatName(bits), ufunc def TypedBinaryFunctions(): for bfunc in BinaryFunctions: for bits in overlayFloatBits: yield floatName(bits), cFloatName(bits), cFuncSuffix(bits), bfunc }% // Unary functions // Note these do not have a corresponding LLVM intrinsic % for T, CT, f, ufunc in TypedUnaryFunctions(): % if T == 'Float80': #if (arch(i386) || arch(x86_64)) && !os(Windows) % end @_transparent public func ${ufunc}(_ x: ${T}) -> ${T} { return ${T}.${ufunc}(x) } % if T == 'Float80': #endif % end % end @_transparent public func cbrt(_ x: Float) -> Float { return Float.root(x, 3) } @available(swift, deprecated: 5.1, message: "Use `x.exponent` or `floor(log2(x))`.") @_transparent public func logb(_ x: Float) -> Float { return Float.log2(x).rounded(.down) } @_transparent public func tgamma(_ x: Float) -> Float { return Float.gamma(x) } #if (arch(i386) || arch(x86_64)) && !os(Windows) @_transparent public func cbrt(_ x: Float80) -> Float80 { return Float80.root(x, 3) } @available(swift, deprecated: 5.1, message: "Use `x.exponent` or `floor(log2(x))`.") @_transparent public func logb(_ x: Float80) -> Float80 { return Float80.log2(x).rounded(.down) } @_transparent public func tgamma(_ x: Float80) -> Float80 { return Float80.gamma(x) } #endif // Unary intrinsic functions // Note these have a corresponding LLVM intrinsic % for T, ufunc in TypedUnaryIntrinsicFunctions(): % if T == 'Float80': #if (arch(i386) || arch(x86_64)) && !os(Windows) % end % if ufunc[-3:] != 'int': @_transparent public func ${ufunc}(_ x: ${T}) -> ${T} { return ${T}.${ufunc}(x) } % else: @available(swift, deprecated: 5.1, message: "Swift does not model dynamic rounding modes, use x.rounded(.toNearestOrEven) instead.") @_transparent public func ${ufunc}(_ x: ${T}) -> ${T} { return x.rounded(.toNearestOrEven) } % end % if T == 'Float80': #endif % end % end // Binary functions % for T, CT, f in OverlayFloatTypes(): % if T == 'Float80': #if (arch(i386) || arch(x86_64)) && !os(Windows) % end @_transparent public func atan2(_ y: ${T}, _ x: ${T}) -> ${T} { return ${T}.atan2(y: y, x: x) } @_transparent public func hypot(_ x: ${T}, _ y: ${T}) -> ${T} { return ${T}.hypot(x, y) } @_transparent public func pow(_ x: ${T}, _ y: ${T}) -> ${T} { return ${T}.pow(x, y) } @_transparent public func copysign(_ x: ${T}, _ y: ${T}) -> ${T} { return ${T}(signOf: y, magnitudeOf: x) } @_transparent public func fdim(_ x: ${T}, _ y: ${T}) -> ${T} { return ${T}(fdim${f}(${CT}(x), ${CT}(y))) } @available(swift, deprecated: 5.1, message: "Use the .nextUp and .nextDown properties.") @_transparent public func nextafter(_ x: ${T}, _ y: ${T}) -> ${T} { return y > x ? x.nextUp : (y < x ? x.nextDown : y) } @available(swift, deprecated: 5.1, message: "Use ${T}.minimum( ) or Swift.min( )") @_transparent public func fmin(_ x: ${T}, _ y: ${T}) -> ${T} { return .minimum(x, y) } @available(swift, deprecated: 5.1, message: "Use ${T}.maximum( ) or Swift.max( )") @_transparent public func fmax(_ x: ${T}, _ y: ${T}) -> ${T} { return .maximum(x, y) } % if T == 'Float80': #endif % end % end % # This is AllFloatTypes not OverlayFloatTypes because of the tuple return. % for T, CT, f in AllFloatTypes(): % if T == 'Float80': #if (arch(i386) || arch(x86_64)) && !os(Windows) % else: // lgamma not available on Windows, apparently? #if !os(Windows) % end @_transparent public func lgamma(_ x: ${T}) -> (${T}, Int) { return (${T}.logGamma(x), ${T}.signGamma(x) == .plus ? 1 : -1) } #endif % end % # This is AllFloatTypes not OverlayFloatTypes because of the tuple return. % for T, CT, f in AllFloatTypes(): % if T == 'Float80': #if (arch(i386) || arch(x86_64)) && !os(Windows) % end @_transparent public func remquo(_ x: ${T}, _ y: ${T}) -> (${T}, Int) { var quo = Int32(0) let rem = remquo${f}(${CT}(x), ${CT}(y), &quo) return (${T}(rem), Int(quo)) } % if T == 'Float80': #endif % end % end % for T, CT, f in OverlayFloatTypes(): % if T == 'Float80': #if (arch(i386) || arch(x86_64)) && !os(Windows) % end @available(swift, deprecated: 4.2/*, obsoleted: 5.1*/, message: "use ${T}(nan: ${T}.RawSignificand).") @_transparent public func nan(_ tag: String) -> ${T} { return ${T}(nan${f}(tag)) } % if T == 'Float80': #endif % end % end % # These C functions only support double. The overlay fixes the Int parameter. @_transparent public func jn(_ n: Int, _ x: Double) -> Double { #if os(Windows) return _jn(Int32(n), x) #else return jn(Int32(n), x) #endif } @_transparent public func yn(_ n: Int, _ x: Double) -> Double { #if os(Windows) return _yn(Int32(n), x) #else return yn(Int32(n), x) #endif } % end // ${'Local Variables'}: // eval: (read-only-mode 1) // End: