@@ -68,30 +68,30 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
68
68
static constexpr int maxDigits{3 - minLog2AnyBit / log10Radix};
69
69
70
70
public:
71
- explicit BigRadixFloatingPointNumber (
71
+ explicit RT_API_ATTRS BigRadixFloatingPointNumber (
72
72
enum FortranRounding rounding = RoundNearest)
73
73
: rounding_{rounding} {}
74
74
75
75
// Converts a binary floating point value.
76
- explicit BigRadixFloatingPointNumber (
76
+ explicit RT_API_ATTRS BigRadixFloatingPointNumber (
77
77
Real, enum FortranRounding = RoundNearest);
78
78
79
- BigRadixFloatingPointNumber &SetToZero () {
79
+ RT_API_ATTRS BigRadixFloatingPointNumber &SetToZero () {
80
80
isNegative_ = false ;
81
81
digits_ = 0 ;
82
82
exponent_ = 0 ;
83
83
return *this ;
84
84
}
85
85
86
86
// Converts decimal floating-point to binary.
87
- ConversionToBinaryResult<PREC> ConvertToBinary ();
87
+ RT_API_ATTRS ConversionToBinaryResult<PREC> ConvertToBinary ();
88
88
89
89
// Parses and converts to binary. Handles leading spaces,
90
90
// "NaN", & optionally-signed "Inf". Does not skip internal
91
91
// spaces.
92
92
// The argument is a reference to a pointer that is left
93
93
// pointing to the first character that wasn't parsed.
94
- ConversionToBinaryResult<PREC> ConvertToBinary (
94
+ RT_API_ATTRS ConversionToBinaryResult<PREC> ConvertToBinary (
95
95
const char *&, const char *end = nullptr );
96
96
97
97
// Formats a decimal floating-point number to a user buffer.
@@ -100,7 +100,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
100
100
// after the last digit; the effective decimal exponent is
101
101
// returned as part of the result structure so that it can be
102
102
// formatted by the client.
103
- ConversionToDecimalResult ConvertToDecimal (
103
+ RT_API_ATTRS ConversionToDecimalResult ConvertToDecimal (
104
104
char *, std::size_t , enum DecimalConversionFlags, int digits) const ;
105
105
106
106
// Discard decimal digits not needed to distinguish this value
@@ -112,21 +112,22 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
112
112
// This minimization necessarily assumes that the value will be
113
113
// emitted and read back into the same (or less precise) format
114
114
// with default rounding to the nearest value.
115
- void Minimize (
115
+ RT_API_ATTRS void Minimize (
116
116
BigRadixFloatingPointNumber &&less, BigRadixFloatingPointNumber &&more);
117
117
118
118
template <typename STREAM> STREAM &Dump (STREAM &) const ;
119
119
120
120
private:
121
- BigRadixFloatingPointNumber (const BigRadixFloatingPointNumber &that)
121
+ RT_API_ATTRS BigRadixFloatingPointNumber (
122
+ const BigRadixFloatingPointNumber &that)
122
123
: digits_{that.digits_ }, exponent_{that.exponent_ },
123
124
isNegative_{that.isNegative_ }, rounding_{that.rounding_ } {
124
125
for (int j{0 }; j < digits_; ++j) {
125
126
digit_[j] = that.digit_ [j];
126
127
}
127
128
}
128
129
129
- bool IsZero () const {
130
+ RT_API_ATTRS bool IsZero () const {
130
131
// Don't assume normalization.
131
132
for (int j{0 }; j < digits_; ++j) {
132
133
if (digit_[j] != 0 ) {
@@ -140,13 +141,13 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
140
141
// (When this happens during decimal-to-binary conversion,
141
142
// there are more digits in the input string than can be
142
143
// represented precisely.)
143
- bool IsFull () const {
144
+ RT_API_ATTRS bool IsFull () const {
144
145
return digits_ == digitLimit_ && digit_[digits_ - 1 ] >= radix / 10 ;
145
146
}
146
147
147
148
// Sets *this to an unsigned integer value.
148
149
// Returns any remainder.
149
- template <typename UINT> UINT SetTo (UINT n) {
150
+ template <typename UINT> RT_API_ATTRS UINT SetTo (UINT n) {
150
151
static_assert (
151
152
std::is_same_v<UINT, common::uint128_t > || std::is_unsigned_v<UINT>);
152
153
SetToZero ();
@@ -173,7 +174,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
173
174
}
174
175
}
175
176
176
- int RemoveLeastOrderZeroDigits () {
177
+ RT_API_ATTRS int RemoveLeastOrderZeroDigits () {
177
178
int remove{0 };
178
179
if (digits_ > 0 && digit_[0 ] == 0 ) {
179
180
while (remove < digits_ && digit_[remove] == 0 ) {
@@ -197,25 +198,25 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
197
198
return remove;
198
199
}
199
200
200
- void RemoveLeadingZeroDigits () {
201
+ RT_API_ATTRS void RemoveLeadingZeroDigits () {
201
202
while (digits_ > 0 && digit_[digits_ - 1 ] == 0 ) {
202
203
--digits_;
203
204
}
204
205
}
205
206
206
- void Normalize () {
207
+ RT_API_ATTRS void Normalize () {
207
208
RemoveLeadingZeroDigits ();
208
209
exponent_ += RemoveLeastOrderZeroDigits () * log10Radix;
209
210
}
210
211
211
212
// This limited divisibility test only works for even divisors of the radix,
212
213
// which is fine since it's only ever used with 2 and 5.
213
- template <int N> bool IsDivisibleBy () const {
214
+ template <int N> RT_API_ATTRS bool IsDivisibleBy () const {
214
215
static_assert (N > 1 && radix % N == 0 , " bad modulus" );
215
216
return digits_ == 0 || (digit_[0 ] % N) == 0 ;
216
217
}
217
218
218
- template <unsigned DIVISOR> int DivideBy () {
219
+ template <unsigned DIVISOR> RT_API_ATTRS int DivideBy () {
219
220
Digit remainder{0 };
220
221
for (int j{digits_ - 1 }; j >= 0 ; --j) {
221
222
Digit q{digit_[j] / DIVISOR};
@@ -226,7 +227,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
226
227
return remainder;
227
228
}
228
229
229
- void DivideByPowerOfTwo (int twoPow) { // twoPow <= log10Radix
230
+ RT_API_ATTRS void DivideByPowerOfTwo (int twoPow) { // twoPow <= log10Radix
230
231
Digit remainder{0 };
231
232
auto mask{(Digit{1 } << twoPow) - 1 };
232
233
auto coeff{radix >> twoPow};
@@ -238,7 +239,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
238
239
}
239
240
240
241
// Returns true on overflow
241
- bool DivideByPowerOfTwoInPlace (int twoPow) {
242
+ RT_API_ATTRS bool DivideByPowerOfTwoInPlace (int twoPow) {
242
243
if (digits_ > 0 ) {
243
244
while (twoPow > 0 ) {
244
245
int chunk{twoPow > log10Radix ? log10Radix : twoPow};
@@ -268,7 +269,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
268
269
return false ; // no overflow
269
270
}
270
271
271
- int AddCarry (int position = 0 , int carry = 1 ) {
272
+ RT_API_ATTRS int AddCarry (int position = 0 , int carry = 1 ) {
272
273
for (; position < digits_; ++position) {
273
274
Digit v{digit_[position] + carry};
274
275
if (v < radix) {
@@ -290,13 +291,13 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
290
291
return carry;
291
292
}
292
293
293
- void Decrement () {
294
+ RT_API_ATTRS void Decrement () {
294
295
for (int j{0 }; digit_[j]-- == 0 ; ++j) {
295
296
digit_[j] = radix - 1 ;
296
297
}
297
298
}
298
299
299
- template <int N> int MultiplyByHelper (int carry = 0 ) {
300
+ template <int N> RT_API_ATTRS int MultiplyByHelper (int carry = 0 ) {
300
301
for (int j{0 }; j < digits_; ++j) {
301
302
auto v{N * digit_[j] + carry};
302
303
carry = v / radix;
@@ -305,15 +306,15 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
305
306
return carry;
306
307
}
307
308
308
- template <int N> int MultiplyBy (int carry = 0 ) {
309
+ template <int N> RT_API_ATTRS int MultiplyBy (int carry = 0 ) {
309
310
if (int newCarry{MultiplyByHelper<N>(carry)}) {
310
311
return AddCarry (digits_, newCarry);
311
312
} else {
312
313
return 0 ;
313
314
}
314
315
}
315
316
316
- template <int N> int MultiplyWithoutNormalization () {
317
+ template <int N> RT_API_ATTRS int MultiplyWithoutNormalization () {
317
318
if (int carry{MultiplyByHelper<N>(0 )}) {
318
319
if (digits_ < digitLimit_) {
319
320
digit_[digits_++] = carry;
@@ -326,9 +327,9 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
326
327
}
327
328
}
328
329
329
- void LoseLeastSignificantDigit (); // with rounding
330
+ RT_API_ATTRS void LoseLeastSignificantDigit (); // with rounding
330
331
331
- void PushCarry (int carry) {
332
+ RT_API_ATTRS void PushCarry (int carry) {
332
333
if (digits_ == maxDigits && RemoveLeastOrderZeroDigits () == 0 ) {
333
334
LoseLeastSignificantDigit ();
334
335
digit_[digits_ - 1 ] += carry;
@@ -340,18 +341,20 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
340
341
// Adds another number and then divides by two.
341
342
// Assumes same exponent and sign.
342
343
// Returns true when the result has effectively been rounded down.
343
- bool Mean (const BigRadixFloatingPointNumber &);
344
+ RT_API_ATTRS bool Mean (const BigRadixFloatingPointNumber &);
344
345
345
346
// Parses a floating-point number; leaves the pointer reference
346
347
// argument pointing at the next character after what was recognized.
347
348
// The "end" argument can be left null if the caller is sure that the
348
349
// string is properly terminated with an addressable character that
349
350
// can't be in a valid floating-point character.
350
- bool ParseNumber (const char *&, bool &inexact, const char *end);
351
+ RT_API_ATTRS bool ParseNumber (const char *&, bool &inexact, const char *end);
351
352
352
353
using Raw = typename Real::RawType;
353
- constexpr Raw SignBit () const { return Raw{isNegative_} << (Real::bits - 1 ); }
354
- constexpr Raw Infinity () const {
354
+ constexpr RT_API_ATTRS Raw SignBit () const {
355
+ return Raw{isNegative_} << (Real::bits - 1 );
356
+ }
357
+ constexpr RT_API_ATTRS Raw Infinity () const {
355
358
Raw result{static_cast <Raw>(Real::maxExponent)};
356
359
result <<= Real::significandBits;
357
360
result |= SignBit ();
@@ -360,7 +363,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
360
363
}
361
364
return result;
362
365
}
363
- constexpr Raw NaN (bool isQuiet = true ) {
366
+ constexpr RT_API_ATTRS Raw NaN (bool isQuiet = true ) {
364
367
Raw result{Real::maxExponent};
365
368
result <<= Real::significandBits;
366
369
result |= SignBit ();
@@ -373,7 +376,7 @@ template <int PREC, int LOG10RADIX = 16> class BigRadixFloatingPointNumber {
373
376
}
374
377
return result;
375
378
}
376
- constexpr Raw HUGE () const {
379
+ constexpr RT_API_ATTRS Raw HUGE () const {
377
380
Raw result{static_cast <Raw>(Real::maxExponent)};
378
381
result <<= Real::significandBits;
379
382
result |= SignBit ();
0 commit comments