mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
The old ones were: - print/println - printAny - printf - Console The new printing story is just print/println. Every object can be printed. You can customize the way it is printed by adopting Printable protocol. Full details in comments inside stdlib/core/OutputStream.swift. Printing is not completely finished yet. We still have ReplPrintable, which should be removed, string interpolation still uses String constructors, and printing objects that don't conform to Printable will result in printing mangled names. Swift SVN r18001
504 lines
13 KiB
Swift
504 lines
13 KiB
Swift
%# -*- mode: swift -*-
|
|
|
|
%# Ignore the following admonition; it applies to the resulting .swift file only
|
|
//// Automatically Generated From FloatingPoint.gyb. Do Not Edit Directly
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See http://swift.org/LICENSE.txt for license information
|
|
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
%{
|
|
#
|
|
# Utility code for later in this template
|
|
#
|
|
|
|
if CMAKE_SYSTEM_PROCESSOR in ('i386', 'x86_64'):
|
|
allFloatBits = [32, 64, 80]
|
|
else:
|
|
# Compile only 32-bit and 64-bit floating point on non-x86 architectures
|
|
allFloatBits = [32, 64]
|
|
|
|
# Bit counts for all int types
|
|
allIntBits = [8, 16, 32, 64, 'Int']
|
|
|
|
# Number of bits in integer literals.
|
|
builtinIntLiteralBits = 2048
|
|
|
|
# Number of bits in floating point literals.
|
|
builtinFloatLiteralBits = 64
|
|
|
|
def allInts():
|
|
for bits in allIntBits:
|
|
for signed in False, True:
|
|
yield bits,signed
|
|
|
|
def baseIntName(name):
|
|
return 'Int' if name == 'Int' else 'Int' + str(name)
|
|
|
|
def builtinIntName(name):
|
|
return 'Word' if name == 'Int' else 'Int' + str(name)
|
|
|
|
def intName(name, signed):
|
|
return ('' if signed else 'U') + baseIntName(name)
|
|
|
|
def floatName(bits):
|
|
if bits == 32:
|
|
return 'Float'
|
|
if bits == 64:
|
|
return 'Double'
|
|
if bits == 80:
|
|
return 'Float80'
|
|
|
|
def cFuncSuffix(bits):
|
|
if bits == 32:
|
|
return 'f'
|
|
if bits == 64:
|
|
return ''
|
|
if bits == 80:
|
|
return 'l'
|
|
|
|
def llvmIntrinsicSuffix(bits):
|
|
if bits == 32:
|
|
return 'f32'
|
|
if bits == 64:
|
|
return 'f64'
|
|
if bits == 80:
|
|
return 'f80'
|
|
|
|
def getInfBitPattern(bits):
|
|
if bits == 32:
|
|
return '0x7f800000'
|
|
if bits == 64:
|
|
return '0x7ff0000000000000'
|
|
return 'error'
|
|
|
|
def getQuietNaNBitPattern(bits):
|
|
if bits == 32:
|
|
return '0x7fc00000'
|
|
if bits == 64:
|
|
return '0x7ff8000000000000'
|
|
return 'error'
|
|
|
|
def getSignalingNanBitPattern(bits):
|
|
if bits == 32:
|
|
return '0x7fa00000'
|
|
if bits == 64:
|
|
return '0x7ff4000000000000'
|
|
return 'error'
|
|
|
|
def getMinNormalBitPattern(bits):
|
|
if bits == 32:
|
|
return '0x00800000'
|
|
if bits == 64:
|
|
return '0x0010000000000000'
|
|
return 'error'
|
|
|
|
def getExponentBitCount(bits):
|
|
if bits == 32:
|
|
return '8'
|
|
if bits == 64:
|
|
return '11'
|
|
return 'error'
|
|
|
|
def getSignificantBitCount(bits):
|
|
if bits == 32:
|
|
return '23'
|
|
if bits == 64:
|
|
return '52'
|
|
return 'error'
|
|
|
|
def getInfinityExponent(bits):
|
|
if bits == 32:
|
|
return '0xff'
|
|
if bits == 64:
|
|
return '0x7ff'
|
|
return 'error'
|
|
|
|
}%
|
|
|
|
% for bits in allFloatBits:
|
|
% Self = floatName(bits)
|
|
|
|
struct ${Self} {
|
|
var value: Builtin.FPIEEE${bits}
|
|
|
|
@transparent
|
|
init() {
|
|
var zero: Int64 = 0
|
|
value = Builtin.uitofp_Int64_FPIEEE${bits}(zero.value)
|
|
}
|
|
|
|
@transparent
|
|
init(_ v: Builtin.FPIEEE${bits}) {
|
|
value = v
|
|
}
|
|
|
|
@transparent
|
|
init(_ value: ${Self}) { self = value }
|
|
}
|
|
|
|
extension ${Self} : ReplPrintable {
|
|
func replPrint() {
|
|
print(self)
|
|
}
|
|
}
|
|
|
|
extension ${Self} : Printable {
|
|
var description: String {
|
|
% if bits == 64:
|
|
return _doubleToString(self)
|
|
% else:
|
|
return _doubleToString(Double(self))
|
|
% end
|
|
}
|
|
}
|
|
|
|
% if bits in allIntBits:
|
|
// Not transparent because the compiler crashes in that case.
|
|
//@transparent
|
|
extension ${Self} : FloatingPointNumber {
|
|
typealias _BitsType = UInt${bits}
|
|
|
|
static func _fromBitPattern(bits: _BitsType) -> ${Self} {
|
|
return ${Self}(Builtin.bitcast_Int${bits}_FPIEEE${bits}(bits.value))
|
|
}
|
|
|
|
func _toBitPattern() -> _BitsType {
|
|
return _BitsType(Builtin.bitcast_FPIEEE${bits}_Int${bits}(value))
|
|
}
|
|
|
|
func __getSignBit() -> Int {
|
|
return Int(_toBitPattern() >> ${bits - 1}) & 1
|
|
}
|
|
|
|
func __getBiasedExponent() -> _BitsType {
|
|
return (_toBitPattern() >> ${getSignificantBitCount(bits)}) & ${getInfinityExponent(bits)}
|
|
}
|
|
|
|
func __getSignificand() -> _BitsType {
|
|
var mask: _BitsType = (1 << ${getSignificantBitCount(bits)}) - 1
|
|
return _toBitPattern() & mask
|
|
}
|
|
|
|
static func inf() -> ${Self} {
|
|
return _fromBitPattern(${getInfBitPattern(bits)})
|
|
}
|
|
|
|
static func NaN() -> ${Self} {
|
|
return quietNaN()
|
|
}
|
|
|
|
static func quietNaN() -> ${Self} {
|
|
return _fromBitPattern(${getQuietNaNBitPattern(bits)})
|
|
}
|
|
|
|
func isSignMinus() -> Bool {
|
|
return __getSignBit() == 1
|
|
}
|
|
|
|
func isNormal() -> Bool {
|
|
var biasedExponent = __getBiasedExponent()
|
|
return biasedExponent != ${getInfinityExponent(bits)} &&
|
|
biasedExponent != 0
|
|
}
|
|
|
|
func isFinite() -> Bool {
|
|
return __getBiasedExponent() != ${getInfinityExponent(bits)}
|
|
}
|
|
|
|
func isZero() -> Bool {
|
|
// Mask out the sign bit.
|
|
var mask: _BitsType = (1 << (${bits} - 1)) - 1
|
|
return (_toBitPattern() & mask) == 0
|
|
}
|
|
|
|
func isSubnormal() -> Bool {
|
|
if __getBiasedExponent() == 0 {
|
|
return __getSignificand() != 0
|
|
}
|
|
return false
|
|
|
|
// Alternative implementation:
|
|
// return !isNan() &&
|
|
// abs(self) < ${Self}._fromBitPattern(${getMinNormalBitPattern(bits)})
|
|
//
|
|
// But because we need to check for !isNan(), and do it safely in case of
|
|
// SNaN, we need to go down to the bit level, so open-coding the combined
|
|
// condition is going to be faster.
|
|
}
|
|
|
|
func isInfinite() -> Bool {
|
|
if __getBiasedExponent() == ${getInfinityExponent(bits)} {
|
|
return __getSignificand() == 0
|
|
}
|
|
return false
|
|
|
|
// Alternative implementation that is not safe in case of SNaN:
|
|
// return abs(self) == ${Self}.inf()
|
|
}
|
|
|
|
func isNaN() -> Bool {
|
|
if __getBiasedExponent() == ${getInfinityExponent(bits)} {
|
|
return __getSignificand() != 0
|
|
}
|
|
return false
|
|
|
|
// Alternative implementation that is not safe in case of SNaN:
|
|
// return self != self
|
|
}
|
|
|
|
func isSignaling() -> Bool {
|
|
if __getBiasedExponent() == ${getInfinityExponent(bits)} {
|
|
// IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded
|
|
// with the first bit of the trailing significand being 0. If the first
|
|
// bit of the trailing significand field is 0, some other bit of the
|
|
// trailing significand field must be non-zero to distinguish the NaN
|
|
// from infinity.
|
|
var significand = __getSignificand()
|
|
if significand != 0 {
|
|
return (significand >> (${getSignificantBitCount(bits)} - 1)) == 0
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
// Not @transparent because the function is too complex.
|
|
extension ${Self} /* : FloatingPointNumber */ {
|
|
var floatingPointClass: FloatingPointClassification {
|
|
get {
|
|
var biasedExponent = __getBiasedExponent()
|
|
if biasedExponent == ${getInfinityExponent(bits)} {
|
|
var significand = __getSignificand()
|
|
// This is either +/-inf or NaN.
|
|
if significand == 0 {
|
|
return isSignMinus() ? .NegativeInfinity : .PositiveInfinity
|
|
}
|
|
var isQNaN = (significand >> (${getSignificantBitCount(bits)} - 1)) == 1
|
|
return isQNaN ? .QuietNaN : .SignalingNaN
|
|
}
|
|
|
|
// OK, the number is finite.
|
|
var isMinus = isSignMinus()
|
|
if biasedExponent != 0 {
|
|
return isMinus ? .NegativeNormal : .PositiveNormal
|
|
}
|
|
|
|
// Exponent is zero.
|
|
if __getSignificand() == 0 {
|
|
return isMinus ? .NegativeZero : .PositiveZero
|
|
}
|
|
return isMinus ? .NegativeSubnormal : .PositiveSubnormal
|
|
}
|
|
}
|
|
}
|
|
% end
|
|
|
|
@transparent
|
|
extension ${Self} : _BuiltinIntegerLiteralConvertible, IntegerLiteralConvertible {
|
|
static func _convertFromBuiltinIntegerLiteral(value: Builtin.Int${builtinIntLiteralBits}) -> ${Self} {
|
|
return ${Self}(Builtin.itofp_with_overflow_Int${builtinIntLiteralBits}_FPIEEE${bits}(value))
|
|
}
|
|
|
|
static func convertFromIntegerLiteral(value: Int64) -> ${Self} {
|
|
return ${Self}(Builtin.uitofp_Int64_FPIEEE${bits}(value.value))
|
|
}
|
|
}
|
|
|
|
@transparent
|
|
extension ${Self} : _BuiltinFloatLiteralConvertible {
|
|
static func _convertFromBuiltinFloatLiteral(value: Builtin.FPIEEE${builtinFloatLiteralBits}) -> ${Self} {
|
|
% if bits == builtinFloatLiteralBits:
|
|
return ${Self}(value)
|
|
% elif bits < builtinFloatLiteralBits:
|
|
return ${Self}(Builtin.fptrunc_FPIEEE${builtinFloatLiteralBits}_FPIEEE${bits}(value))
|
|
% else:
|
|
// FIXME: This is actually losing precision <rdar://problem/14073102>.
|
|
return ${Self}(Builtin.fpext_FPIEEE${builtinFloatLiteralBits}_FPIEEE${bits}(value))
|
|
% end
|
|
}
|
|
}
|
|
|
|
@transparent
|
|
extension ${Self} : FloatLiteralConvertible {
|
|
static func convertFromFloatLiteral(value: ${Self}) -> ${Self} {
|
|
return value
|
|
}
|
|
}
|
|
|
|
@transparent
|
|
func ==(lhs: ${Self}, rhs: ${Self}) -> Bool {
|
|
return Bool(Builtin.fcmp_oeq_FPIEEE${bits}(lhs.value, rhs.value))
|
|
}
|
|
|
|
@transparent
|
|
func <(lhs: ${Self}, rhs: ${Self}) -> Bool {
|
|
return Bool(Builtin.fcmp_olt_FPIEEE${bits}(lhs.value, rhs.value))
|
|
}
|
|
|
|
@transparent
|
|
extension ${Self} : Comparable {
|
|
}
|
|
|
|
extension ${Self} : Hashable {
|
|
var hashValue: Int {
|
|
var asBuiltinInt = Builtin.bitcast_FPIEEE${bits}_Int${bits}(value)
|
|
% if bits >= 64:
|
|
return Int(Builtin.truncOrBitCast_Int${bits}_Word(asBuiltinInt))
|
|
% elif bits <= 32:
|
|
return Int(Builtin.sextOrBitCast_Int${bits}_Word(asBuiltinInt))
|
|
% else:
|
|
error unhandled float size ${bits}
|
|
% end
|
|
}
|
|
}
|
|
|
|
@transparent
|
|
extension ${Self} : AbsoluteValuable {
|
|
@transparent
|
|
static func abs(x: ${Self}) -> ${Self} {
|
|
return ${Self}(Builtin.int_fabs_FPIEEE${bits}(x.value))
|
|
}
|
|
}
|
|
|
|
@prefix @transparent
|
|
func -(x: ${Self}) -> ${Self} {
|
|
return ${Self}(Builtin.fneg_FPIEEE${bits}(x.value))
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Explicit conversions between types.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Construction from integers.
|
|
@transparent
|
|
extension ${Self} {
|
|
% for (srcBits, srcSigned) in allInts():
|
|
% That = intName(srcBits, srcSigned)
|
|
% ThatBuiltinName = builtinIntName(srcBits)
|
|
% sign = 's' if srcSigned else 'u'
|
|
init(_ v: ${That}) {
|
|
value = Builtin.${sign}itofp_${ThatBuiltinName}_FPIEEE${bits}(v.value)
|
|
}
|
|
% end
|
|
}
|
|
|
|
// Construction from other floating point numbers.
|
|
@transparent
|
|
extension ${Self} {
|
|
% for srcBits in allFloatBits:
|
|
% That = floatName(srcBits)
|
|
% if Self != That:
|
|
init(_ v: ${That}) {
|
|
% if srcBits > bits:
|
|
value = Builtin.fptrunc_FPIEEE${srcBits}_FPIEEE${bits}(v.value)
|
|
% else:
|
|
value = Builtin.fpext_FPIEEE${srcBits}_FPIEEE${bits}(v.value)
|
|
% end
|
|
}
|
|
% end
|
|
% end
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Standard Operator Table
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Unary plus
|
|
@transparent @prefix
|
|
func + (rhs: ${Self}) -> ${Self} { return rhs }
|
|
|
|
@transparent @prefix @assignment
|
|
func ++ (inout rhs: ${Self}) -> ${Self} { rhs += 1.0; return rhs }
|
|
@transparent @prefix @assignment
|
|
func -- (inout rhs: ${Self}) -> ${Self} { rhs -= 1.0; return rhs }
|
|
@transparent @postfix @assignment
|
|
func ++ (inout lhs: ${Self}) -> ${Self} { let tmp = lhs; lhs += 1.0; return tmp }
|
|
@transparent @postfix @assignment
|
|
func -- (inout lhs: ${Self}) -> ${Self} { let tmp = lhs; lhs -= 1.0; return tmp }
|
|
|
|
|
|
|
|
@transparent
|
|
extension ${Self} : RandomAccessIndex {
|
|
@transparent
|
|
func succ() -> ${Self} {
|
|
return self + 1.0
|
|
}
|
|
@transparent
|
|
func pred() -> ${Self} {
|
|
return self - 1.0
|
|
}
|
|
|
|
@transparent
|
|
func distanceTo(other: ${Self}) -> ${Self}.DistanceType {
|
|
return Int(other-self)
|
|
}
|
|
|
|
@transparent
|
|
func advancedBy(amount: ${Self}.DistanceType) -> ${Self} {
|
|
return self + ${Self}(amount)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
% for op, name in ('+','fadd'), ('-','fsub'),('*','fmul'), ('/','fdiv'):
|
|
@transparent
|
|
func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
|
|
return ${Self}(Builtin.${name}_FPIEEE${bits}(lhs.value, rhs.value))
|
|
}
|
|
% end
|
|
|
|
// Binary Remainder.
|
|
// The sign of the result matches the sign of the dividend.
|
|
// 1) This is consistent with '%' in C#, D, Java, and JavaScript
|
|
// 2) C99 requires this behavior for fmod*()
|
|
// 3) C++11 requires this behavior for std::fmod*()
|
|
@asmname("fmod${cFuncSuffix(bits)}")
|
|
func % (lhs: ${Self}, rhs: ${Self}) -> ${Self}
|
|
|
|
// See Bool.swift for && and ||
|
|
// In C, 120 is &&
|
|
// In C, 110 is ||
|
|
|
|
// In C, 100 is ?:
|
|
// In C, 90 is =, *=, += etc.
|
|
|
|
% for op in '+', '-', '*', '/', '%':
|
|
@transparent @assignment
|
|
func ${op}= (inout lhs: ${Self}, rhs: ${Self}) { lhs = lhs ${op} rhs }
|
|
% end
|
|
|
|
% end # for bits in allFloatBits
|
|
|
|
// Construction of integers from floating point numbers.
|
|
% for (bits, signed) in allInts():
|
|
% sign = 's' if signed else 'u'
|
|
% Self = intName(bits, signed)
|
|
% BuiltinName = builtinIntName(bits)
|
|
@transparent
|
|
extension ${Self} {
|
|
% for srcBits in allFloatBits:
|
|
% That = floatName(srcBits)
|
|
init(_ v: ${That}) {
|
|
assert(v >= ${That}(${Self}.min))
|
|
assert(v <= ${That}(${Self}.max))
|
|
value = Builtin.fpto${sign}i_FPIEEE${srcBits}_${BuiltinName}(v.value)
|
|
}
|
|
% end
|
|
}
|
|
|
|
% end
|
|
|
|
// ${'Local Variables'}:
|
|
// eval: (read-only-mode 1)
|
|
// End:
|