Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
f32_rem.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 f32_rem.c:

Go to the source code of this file.

Functions

float32_t f32_rem (float32_t a, float32_t b)
 

Function Documentation

◆ f32_rem()

float32_t f32_rem ( float32_t a,
float32_t b )

Definition at line 44 of file f32_rem.c.

45{
46 union ui32_f32 uA;
47 uint_fast32_t uiA;
48 bool signA;
49 int_fast16_t expA;
50 uint_fast32_t sigA;
51 union ui32_f32 uB;
52 uint_fast32_t uiB;
53 int_fast16_t expB;
54 uint_fast32_t sigB;
55 struct exp16_sig32 normExpSig;
56 uint32_t rem;
57 int_fast16_t expDiff;
58 uint32_t q, recip32, altRem, meanRem;
59 bool signRem;
60 uint_fast32_t uiZ;
61 union ui32_f32 uZ;
62
63 /*------------------------------------------------------------------------
64 *------------------------------------------------------------------------*/
65 uA.f = a;
66 uiA = uA.ui;
67 signA = signF32UI( uiA );
68 expA = expF32UI( uiA );
69 sigA = fracF32UI( uiA );
70 uB.f = b;
71 uiB = uB.ui;
72 expB = expF32UI( uiB );
73 sigB = fracF32UI( uiB );
74 /*------------------------------------------------------------------------
75 *------------------------------------------------------------------------*/
76 if ( expA == 0xFF ) {
77 if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN;
78 goto invalid;
79 }
80 if ( expB == 0xFF ) {
81 if ( sigB ) goto propagateNaN;
82 return a;
83 }
84 /*------------------------------------------------------------------------
85 *------------------------------------------------------------------------*/
86 if ( ! expB ) {
87 if ( ! sigB ) goto invalid;
88 normExpSig = softfloat_normSubnormalF32Sig( sigB );
89 expB = normExpSig.exp;
90 sigB = normExpSig.sig;
91 }
92 if ( ! expA ) {
93 if ( ! sigA ) return a;
94 normExpSig = softfloat_normSubnormalF32Sig( sigA );
95 expA = normExpSig.exp;
96 sigA = normExpSig.sig;
97 }
98 /*------------------------------------------------------------------------
99 *------------------------------------------------------------------------*/
100 rem = sigA | 0x00800000;
101 sigB |= 0x00800000;
102 expDiff = expA - expB;
103 if ( expDiff < 1 ) {
104 if ( expDiff < -1 ) return a;
105 sigB <<= 6;
106 if ( expDiff ) {
107 rem <<= 5;
108 q = 0;
109 } else {
110 rem <<= 6;
111 q = (sigB <= rem);
112 if ( q ) rem -= sigB;
113 }
114 } else {
115 recip32 = softfloat_approxRecip32_1( sigB<<8 );
116 /*--------------------------------------------------------------------
117 | Changing the shift of `rem' here requires also changing the initial
118 | subtraction from `expDiff'.
119 *--------------------------------------------------------------------*/
120 rem <<= 7;
121 expDiff -= 31;
122 /*--------------------------------------------------------------------
123 | The scale of `sigB' affects how many bits are obtained during each
124 | cycle of the loop. Currently this is 29 bits per loop iteration,
125 | which is believed to be the maximum possible.
126 *--------------------------------------------------------------------*/
127 sigB <<= 6;
128 for (;;) {
129 q = (rem * (uint_fast64_t) recip32)>>32;
130 if ( expDiff < 0 ) break;
131 rem = -(q * (uint32_t) sigB);
132 expDiff -= 29;
133 }
134 /*--------------------------------------------------------------------
135 | (`expDiff' cannot be less than -30 here.)
136 *--------------------------------------------------------------------*/
137 q >>= ~expDiff & 31;
138 rem = (rem<<(expDiff + 30)) - q * (uint32_t) sigB;
139 }
140 /*------------------------------------------------------------------------
141 *------------------------------------------------------------------------*/
142 do {
143 altRem = rem;
144 ++q;
145 rem -= sigB;
146 } while ( ! (rem & 0x80000000) );
147 meanRem = rem + altRem;
148 if ( (meanRem & 0x80000000) || (! meanRem && (q & 1)) ) rem = altRem;
149 signRem = signA;
150 if ( 0x80000000 <= rem ) {
151 signRem = ! signRem;
152 rem = -rem;
153 }
154 return softfloat_normRoundPackToF32( signRem, expB, rem );
155 /*------------------------------------------------------------------------
156 *------------------------------------------------------------------------*/
157 propagateNaN:
158 uiZ = softfloat_propagateNaNF32UI( uiA, uiB );
159 goto uiZ;
160 invalid:
162 uiZ = defaultNaNF32UI;
163 uiZ:
164 uZ.ui = uiZ;
165 return uZ.f;
166
167}
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB)
void softfloat_raiseFlags(uint_fast8_t flags)
#define defaultNaNF32UI
Definition specialize.h:123
#define expF32UI(a)
Definition internals.h:105
struct exp16_sig32 softfloat_normSubnormalF32Sig(uint_fast32_t)
#define fracF32UI(a)
Definition internals.h:106
#define signF32UI(a)
Definition internals.h:104
float32_t softfloat_normRoundPackToF32(bool, int_fast16_t, uint_fast32_t)
uint32_t softfloat_approxRecip32_1(uint32_t a)
@ softfloat_flag_invalid
Definition softfloat.h:89
unsigned int uint32_t
Definition stdint.h:126
uint64_t uint_fast64_t
Definition stdint.h:157
uint32_t uint_fast32_t
Definition stdint.h:156
int16_t int_fast16_t
Definition stdint.h:151
float32_t f
Definition internals.h:46
Here is the call graph for this function: