Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
f128_roundToInt.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include "platform.h"
#include "internals.h"
#include "specialize.h"
#include "softfloat.h"
Include dependency graph for f128_roundToInt.c:

Go to the source code of this file.

Functions

float128_t f128_roundToInt (float128_t a, uint_fast8_t roundingMode, bool exact)
 

Function Documentation

◆ f128_roundToInt()

float128_t f128_roundToInt ( float128_t a,
uint_fast8_t roundingMode,
bool exact )

Definition at line 45 of file f128_roundToInt.c.

46{
47 union ui128_f128 uA;
48 uint_fast64_t uiA64, uiA0;
49 int_fast32_t exp;
50 struct uint128 uiZ;
51 uint_fast64_t lastBitMask0, roundBitsMask;
52 bool roundNearEven;
53 uint_fast64_t lastBitMask64;
54 union ui128_f128 uZ;
55
56 /*------------------------------------------------------------------------
57 *------------------------------------------------------------------------*/
58 uA.f = a;
59 uiA64 = uA.ui.v64;
60 uiA0 = uA.ui.v0;
61 exp = expF128UI64( uiA64 );
62 /*------------------------------------------------------------------------
63 *------------------------------------------------------------------------*/
64 if ( 0x402F <= exp ) {
65 /*--------------------------------------------------------------------
66 *--------------------------------------------------------------------*/
67 if ( 0x406F <= exp ) {
68 if ( (exp == 0x7FFF) && (fracF128UI64( uiA64 ) | uiA0) ) {
69 uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, 0, 0 );
70 goto uiZ;
71 }
72 return a;
73 }
74 /*--------------------------------------------------------------------
75 *--------------------------------------------------------------------*/
76 lastBitMask0 = (uint_fast64_t) 2<<(0x406E - exp);
77 roundBitsMask = lastBitMask0 - 1;
78 uiZ.v64 = uiA64;
79 uiZ.v0 = uiA0;
80 roundNearEven = (roundingMode == softfloat_round_near_even);
81 if ( roundNearEven || (roundingMode == softfloat_round_near_maxMag) ) {
82 if ( exp == 0x402F ) {
83 if ( UINT64_C( 0x8000000000000000 ) <= uiZ.v0 ) {
84 ++uiZ.v64;
85 if (
86 roundNearEven
87 && (uiZ.v0 == UINT64_C( 0x8000000000000000 ))
88 ) {
89 uiZ.v64 &= ~1;
90 }
91 }
92 } else {
93 uiZ = softfloat_add128( uiZ.v64, uiZ.v0, 0, lastBitMask0>>1 );
94 if ( roundNearEven && !(uiZ.v0 & roundBitsMask) ) {
95 uiZ.v0 &= ~lastBitMask0;
96 }
97 }
98 } else if (
99 roundingMode
100 == (signF128UI64( uiZ.v64 ) ? softfloat_round_min
102 ) {
103 uiZ = softfloat_add128( uiZ.v64, uiZ.v0, 0, roundBitsMask );
104 }
105 uiZ.v0 &= ~roundBitsMask;
106 lastBitMask64 = !lastBitMask0;
107 } else {
108 /*--------------------------------------------------------------------
109 *--------------------------------------------------------------------*/
110 if ( exp < 0x3FFF ) {
111 if ( !((uiA64 & UINT64_C( 0x7FFFFFFFFFFFFFFF )) | uiA0) ) return a;
113 uiZ.v64 = uiA64 & packToF128UI64( 1, 0, 0 );
114 uiZ.v0 = 0;
115 switch ( roundingMode ) {
117 if ( !(fracF128UI64( uiA64 ) | uiA0) ) break;
119 if ( exp == 0x3FFE ) uiZ.v64 |= packToF128UI64( 0, 0x3FFF, 0 );
120 break;
122 if ( uiZ.v64 ) uiZ.v64 = packToF128UI64( 1, 0x3FFF, 0 );
123 break;
125 if ( !uiZ.v64 ) uiZ.v64 = packToF128UI64( 0, 0x3FFF, 0 );
126 break;
127#ifdef SOFTFLOAT_ROUND_ODD
129 uiZ.v64 |= packToF128UI64( 0, 0x3FFF, 0 );
130 break;
131#endif
132 }
133 goto uiZ;
134 }
135 /*--------------------------------------------------------------------
136 *--------------------------------------------------------------------*/
137 uiZ.v64 = uiA64;
138 uiZ.v0 = 0;
139 lastBitMask64 = (uint_fast64_t) 1<<(0x402F - exp);
140 roundBitsMask = lastBitMask64 - 1;
141 if ( roundingMode == softfloat_round_near_maxMag ) {
142 uiZ.v64 += lastBitMask64>>1;
143 } else if ( roundingMode == softfloat_round_near_even ) {
144 uiZ.v64 += lastBitMask64>>1;
145 if ( !((uiZ.v64 & roundBitsMask) | uiA0) ) {
146 uiZ.v64 &= ~lastBitMask64;
147 }
148 } else if (
149 roundingMode
150 == (signF128UI64( uiZ.v64 ) ? softfloat_round_min
152 ) {
153 uiZ.v64 = (uiZ.v64 | (uiA0 != 0)) + roundBitsMask;
154 }
155 uiZ.v64 &= ~roundBitsMask;
156 lastBitMask0 = 0;
157 }
158 if ( (uiZ.v64 != uiA64) || (uiZ.v0 != uiA0) ) {
159#ifdef SOFTFLOAT_ROUND_ODD
160 if ( roundingMode == softfloat_round_odd ) {
161 uiZ.v64 |= lastBitMask64;
162 uiZ.v0 |= lastBitMask0;
163 }
164#endif
166 }
167 uiZ:
168 uZ.ui = uiZ;
169 return uZ.f;
170
171}
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0)
@ softfloat_flag_inexact
Definition softfloat.h:85
THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags
@ softfloat_round_odd
Definition softfloat.h:77
@ softfloat_round_max
Definition softfloat.h:75
@ softfloat_round_min
Definition softfloat.h:74
@ softfloat_round_near_even
Definition softfloat.h:72
@ softfloat_round_near_maxMag
Definition softfloat.h:76
struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
Definition s_add128.c:44
uint64_t uint_fast64_t
Definition stdint.h:157
#define UINT64_C(val)
Definition stdint.h:284
int32_t int_fast32_t
Definition stdint.h:152
Here is the call graph for this function: