Skip to content

Commit 905dd71

Browse files
authored
Merge pull request #14502 from xwu/floating-point-constants
[stdlib] Specialize floating-point constants for performance
2 parents 43435af + 6b6fa0d commit 905dd71

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

stdlib/public/core/FloatingPoint.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1612,7 +1612,7 @@ extension FloatingPoint {
16121612
/// `FLT_EPSILON`, `DBL_EPSILON`, and others with a similar purpose.
16131613
@_inlineable // FIXME(sil-serialize-all)
16141614
public static var ulpOfOne: Self {
1615-
return Self(1).ulp
1615+
return (1 as Self).ulp
16161616
}
16171617

16181618
/// Returns this value rounded to an integral value using the specified

stdlib/public/core/FloatingPointTypes.swift.gyb

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,9 +480,21 @@ extension ${Self}: BinaryFloatingPoint {
480480
/// // y > x
481481
@_inlineable // FIXME(sil-serialize-all)
482482
public static var infinity: ${Self} {
483+
%if bits == 32:
484+
return ${Self}(bitPattern: 0b0_11111111_00000000000000000000000)
485+
%elif bits == 64:
486+
return ${Self}(
487+
bitPattern: 0b0_11111111111_0000000000000000000000000000000000000000000000000000)
488+
%elif bits == 80:
489+
let rep = _Float80Representation(
490+
explicitSignificand: ${Self}._explicitBitMask,
491+
signAndExponent: 0b0_111111111111111)
492+
return unsafeBitCast(rep, to: ${Self}.self)
493+
%else:
483494
return ${Self}(sign: .plus,
484495
exponentBitPattern: _infinityExponent,
485496
significandBitPattern: 0)
497+
%end
486498
}
487499

488500
/// A quiet NaN ("not a number").
@@ -507,7 +519,19 @@ extension ${Self}: BinaryFloatingPoint {
507519
/// // Prints "true"
508520
@_inlineable // FIXME(sil-serialize-all)
509521
public static var nan: ${Self} {
522+
%if bits == 32:
523+
return ${Self}(bitPattern: 0b0_11111111_10000000000000000000000)
524+
%elif bits == 64:
525+
return ${Self}(
526+
bitPattern: 0b0_11111111111_1000000000000000000000000000000000000000000000000000)
527+
%elif bits == 80:
528+
let rep = _Float80Representation(
529+
explicitSignificand: ${Self}._explicitBitMask | ${Self}._quietNaNMask,
530+
signAndExponent: 0b0_111111111111111)
531+
return unsafeBitCast(rep, to: ${Self}.self)
532+
%else:
510533
return ${Self}(nan: 0, signaling: false)
534+
%end
511535
}
512536

513537
/// A signaling NaN ("not a number").
@@ -531,7 +555,7 @@ extension ${Self}: BinaryFloatingPoint {
531555
}
532556

533557
@available(*, unavailable, renamed: "nan")
534-
public static var quietNaN: ${Self} { Builtin.unreachable()}
558+
public static var quietNaN: ${Self} { Builtin.unreachable() }
535559

536560
/// The greatest finite number representable by this type.
537561
///
@@ -543,9 +567,17 @@ extension ${Self}: BinaryFloatingPoint {
543567
/// `infinity` is greater than this value.
544568
@_inlineable // FIXME(sil-serialize-all)
545569
public static var greatestFiniteMagnitude: ${Self} {
570+
%if bits == 32:
571+
return 0x1.fffffep127
572+
%elif bits == 64:
573+
return 0x1.fffffffffffffp1023
574+
%elif bits == 80:
575+
return 0x1.fffffffffffffffep16383
576+
%else:
546577
return ${Self}(sign: .plus,
547578
exponentBitPattern: _infinityExponent - 1,
548579
significandBitPattern: _significandMask)
580+
%end
549581
}
550582

551583
/// The mathematical constant pi.
@@ -627,9 +659,17 @@ extension ${Self}: BinaryFloatingPoint {
627659
/// subnormals, zeros, and negative numbers are smaller than this value.
628660
@_inlineable // FIXME(sil-serialize-all)
629661
public static var leastNormalMagnitude: ${Self} {
662+
%if bits == 32:
663+
return 0x1p-126
664+
%elif bits == 64:
665+
return 0x1p-1022
666+
%elif bits == 80:
667+
return 0x1p-16382
668+
%else:
630669
return ${Self}(sign: .plus,
631670
exponentBitPattern: 1,
632671
significandBitPattern: 0)
672+
%end
633673
}
634674

635675
/// The least positive number.
@@ -643,12 +683,36 @@ extension ${Self}: BinaryFloatingPoint {
643683
#if arch(arm)
644684
return leastNormalMagnitude
645685
#else
686+
%if bits == 32:
687+
return 0x1p-149
688+
%elif bits == 64:
689+
return 0x1p-1074
690+
%elif bits == 80:
691+
return 0x1p-16445
692+
%else:
646693
return ${Self}(sign: .plus,
647694
exponentBitPattern: 0,
648695
significandBitPattern: 1)
696+
%end
649697
#endif
650698
}
651699

700+
/// The unit in the last place of 1.0.
701+
///
702+
/// The positive difference between 1.0 and the next greater representable
703+
/// number. The `ulpOfOne` constant corresponds to the C macros
704+
/// `FLT_EPSILON`, `DBL_EPSILON`, and others with a similar purpose.
705+
@_inlineable // FIXME(sil-serialize-all)
706+
public static var ulpOfOne: ${Self} {
707+
%if bits == 32:
708+
return 0x1p-23
709+
%elif bits == 64:
710+
return 0x1p-52
711+
%elif bits == 80:
712+
return 0x1p-63
713+
%end
714+
}
715+
652716
/// The exponent of the floating-point value.
653717
///
654718
/// The *exponent* of a floating-point value is the integer part of the

0 commit comments

Comments
 (0)