Statistics
| Branch: | Revision:

root / fpu / softfloat-specialize.h @ 6fb6d245

History | View | Annotate | Download (20.2 kB)

1

    
2
/*============================================================================
3

4
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5
Arithmetic Package, Release 2b.
6

7
Written by John R. Hauser.  This work was made possible in part by the
8
International Computer Science Institute, located at Suite 600, 1947 Center
9
Street, Berkeley, California 94704.  Funding was partially provided by the
10
National Science Foundation under grant MIP-9311980.  The original version
11
of this code was written as part of a project to build a fixed-point vector
12
processor in collaboration with the University of California at Berkeley,
13
overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
14
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
15
arithmetic/SoftFloat.html'.
16

17
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
18
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
19
RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
20
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
21
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
22
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
23
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
24
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
25

26
Derivative works are acceptable, even for commercial purposes, so long as
27
(1) the source code for the derivative work includes prominent notice that
28
the work is derivative, and (2) the source code includes prominent notice with
29
these four paragraphs for those parts of this code that are retained.
30

31
=============================================================================*/
32

    
33
#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
34
#define SNAN_BIT_IS_ONE                1
35
#else
36
#define SNAN_BIT_IS_ONE                0
37
#endif
38

    
39
/*----------------------------------------------------------------------------
40
| Raises the exceptions specified by `flags'.  Floating-point traps can be
41
| defined here if desired.  It is currently not possible for such a trap
42
| to substitute a result value.  If traps are not implemented, this routine
43
| should be simply `float_exception_flags |= flags;'.
44
*----------------------------------------------------------------------------*/
45

    
46
void float_raise( int8 flags STATUS_PARAM )
47
{
48
    STATUS(float_exception_flags) |= flags;
49
}
50

    
51
/*----------------------------------------------------------------------------
52
| Internal canonical NaN format.
53
*----------------------------------------------------------------------------*/
54
typedef struct {
55
    flag sign;
56
    bits64 high, low;
57
} commonNaNT;
58

    
59
/*----------------------------------------------------------------------------
60
| The pattern for a default generated single-precision NaN.
61
*----------------------------------------------------------------------------*/
62
#if defined(TARGET_SPARC)
63
#define float32_default_nan make_float32(0x7FFFFFFF)
64
#elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
65
#define float32_default_nan make_float32(0x7FC00000)
66
#elif defined(TARGET_HPPA)
67
#define float32_default_nan make_float32(0x7FA00000)
68
#elif SNAN_BIT_IS_ONE
69
#define float32_default_nan make_float32(0x7FBFFFFF)
70
#else
71
#define float32_default_nan make_float32(0xFFC00000)
72
#endif
73

    
74
/*----------------------------------------------------------------------------
75
| Returns 1 if the single-precision floating-point value `a' is a quiet
76
| NaN; otherwise returns 0.
77
*----------------------------------------------------------------------------*/
78

    
79
int float32_is_nan( float32 a_ )
80
{
81
    uint32_t a = float32_val(a_);
82
#if SNAN_BIT_IS_ONE
83
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
84
#else
85
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
86
#endif
87
}
88

    
89
/*----------------------------------------------------------------------------
90
| Returns 1 if the single-precision floating-point value `a' is a signaling
91
| NaN; otherwise returns 0.
92
*----------------------------------------------------------------------------*/
93

    
94
int float32_is_signaling_nan( float32 a_ )
95
{
96
    uint32_t a = float32_val(a_);
97
#if SNAN_BIT_IS_ONE
98
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
99
#else
100
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
101
#endif
102
}
103

    
104
/*----------------------------------------------------------------------------
105
| Returns the result of converting the single-precision floating-point NaN
106
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
107
| exception is raised.
108
*----------------------------------------------------------------------------*/
109

    
110
static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
111
{
112
    commonNaNT z;
113

    
114
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
115
    z.sign = float32_val(a)>>31;
116
    z.low = 0;
117
    z.high = ( (bits64) float32_val(a) )<<41;
118
    return z;
119
}
120

    
121
/*----------------------------------------------------------------------------
122
| Returns the result of converting the canonical NaN `a' to the single-
123
| precision floating-point format.
124
*----------------------------------------------------------------------------*/
125

    
126
static float32 commonNaNToFloat32( commonNaNT a )
127
{
128
    bits32 mantissa = a.high>>41;
129
    if ( mantissa )
130
        return make_float32(
131
            ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
132
    else
133
        return float32_default_nan;
134
}
135

    
136
/*----------------------------------------------------------------------------
137
| Takes two single-precision floating-point values `a' and `b', one of which
138
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
139
| signaling NaN, the invalid exception is raised.
140
*----------------------------------------------------------------------------*/
141

    
142
static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
143
{
144
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
145
    bits32 av, bv, res;
146

    
147
    if ( STATUS(default_nan_mode) )
148
        return float32_default_nan;
149

    
150
    aIsNaN = float32_is_nan( a );
151
    aIsSignalingNaN = float32_is_signaling_nan( a );
152
    bIsNaN = float32_is_nan( b );
153
    bIsSignalingNaN = float32_is_signaling_nan( b );
154
    av = float32_val(a);
155
    bv = float32_val(b);
156
#if SNAN_BIT_IS_ONE
157
    av &= ~0x00400000;
158
    bv &= ~0x00400000;
159
#else
160
    av |= 0x00400000;
161
    bv |= 0x00400000;
162
#endif
163
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
164
    if ( aIsSignalingNaN ) {
165
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
166
        res = bIsNaN ? bv : av;
167
    }
168
    else if ( aIsNaN ) {
169
        if ( bIsSignalingNaN || ! bIsNaN )
170
            res = av;
171
        else {
172
 returnLargerSignificand:
173
            if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
174
                res = bv;
175
            else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
176
                res = av;
177
            else
178
                res = ( av < bv ) ? av : bv;
179
        }
180
    }
181
    else {
182
        res = bv;
183
    }
184
    return make_float32(res);
185
}
186

    
187
/*----------------------------------------------------------------------------
188
| The pattern for a default generated double-precision NaN.
189
*----------------------------------------------------------------------------*/
190
#if defined(TARGET_SPARC)
191
#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
192
#elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
193
#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
194
#elif defined(TARGET_HPPA)
195
#define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
196
#elif SNAN_BIT_IS_ONE
197
#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
198
#else
199
#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
200
#endif
201

    
202
/*----------------------------------------------------------------------------
203
| Returns 1 if the double-precision floating-point value `a' is a quiet
204
| NaN; otherwise returns 0.
205
*----------------------------------------------------------------------------*/
206

    
207
int float64_is_nan( float64 a_ )
208
{
209
    bits64 a = float64_val(a_);
210
#if SNAN_BIT_IS_ONE
211
    return
212
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
213
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
214
#else
215
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
216
#endif
217
}
218

    
219
/*----------------------------------------------------------------------------
220
| Returns 1 if the double-precision floating-point value `a' is a signaling
221
| NaN; otherwise returns 0.
222
*----------------------------------------------------------------------------*/
223

    
224
int float64_is_signaling_nan( float64 a_ )
225
{
226
    bits64 a = float64_val(a_);
227
#if SNAN_BIT_IS_ONE
228
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
229
#else
230
    return
231
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
232
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
233
#endif
234
}
235

    
236
/*----------------------------------------------------------------------------
237
| Returns the result of converting the double-precision floating-point NaN
238
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
239
| exception is raised.
240
*----------------------------------------------------------------------------*/
241

    
242
static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
243
{
244
    commonNaNT z;
245

    
246
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
247
    z.sign = float64_val(a)>>63;
248
    z.low = 0;
249
    z.high = float64_val(a)<<12;
250
    return z;
251
}
252

    
253
/*----------------------------------------------------------------------------
254
| Returns the result of converting the canonical NaN `a' to the double-
255
| precision floating-point format.
256
*----------------------------------------------------------------------------*/
257

    
258
static float64 commonNaNToFloat64( commonNaNT a )
259
{
260
    bits64 mantissa = a.high>>12;
261

    
262
    if ( mantissa )
263
        return make_float64(
264
              ( ( (bits64) a.sign )<<63 )
265
            | LIT64( 0x7FF0000000000000 )
266
            | ( a.high>>12 ));
267
    else
268
        return float64_default_nan;
269
}
270

    
271
/*----------------------------------------------------------------------------
272
| Takes two double-precision floating-point values `a' and `b', one of which
273
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
274
| signaling NaN, the invalid exception is raised.
275
*----------------------------------------------------------------------------*/
276

    
277
static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
278
{
279
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
280
    bits64 av, bv, res;
281

    
282
    if ( STATUS(default_nan_mode) )
283
        return float64_default_nan;
284

    
285
    aIsNaN = float64_is_nan( a );
286
    aIsSignalingNaN = float64_is_signaling_nan( a );
287
    bIsNaN = float64_is_nan( b );
288
    bIsSignalingNaN = float64_is_signaling_nan( b );
289
    av = float64_val(a);
290
    bv = float64_val(b);
291
#if SNAN_BIT_IS_ONE
292
    av &= ~LIT64( 0x0008000000000000 );
293
    bv &= ~LIT64( 0x0008000000000000 );
294
#else
295
    av |= LIT64( 0x0008000000000000 );
296
    bv |= LIT64( 0x0008000000000000 );
297
#endif
298
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
299
    if ( aIsSignalingNaN ) {
300
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
301
        res = bIsNaN ? bv : av;
302
    }
303
    else if ( aIsNaN ) {
304
        if ( bIsSignalingNaN || ! bIsNaN )
305
            res = av;
306
        else {
307
 returnLargerSignificand:
308
            if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
309
                res = bv;
310
            else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
311
                res = av;
312
            else
313
                res = ( av < bv ) ? av : bv;
314
        }
315
    }
316
    else {
317
        res = bv;
318
    }
319
    return make_float64(res);
320
}
321

    
322
#ifdef FLOATX80
323

    
324
/*----------------------------------------------------------------------------
325
| The pattern for a default generated extended double-precision NaN.  The
326
| `high' and `low' values hold the most- and least-significant bits,
327
| respectively.
328
*----------------------------------------------------------------------------*/
329
#if SNAN_BIT_IS_ONE
330
#define floatx80_default_nan_high 0x7FFF
331
#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
332
#else
333
#define floatx80_default_nan_high 0xFFFF
334
#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
335
#endif
336

    
337
/*----------------------------------------------------------------------------
338
| Returns 1 if the extended double-precision floating-point value `a' is a
339
| quiet NaN; otherwise returns 0.
340
*----------------------------------------------------------------------------*/
341

    
342
int floatx80_is_nan( floatx80 a )
343
{
344
#if SNAN_BIT_IS_ONE
345
    bits64 aLow;
346

    
347
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
348
    return
349
           ( ( a.high & 0x7FFF ) == 0x7FFF )
350
        && (bits64) ( aLow<<1 )
351
        && ( a.low == aLow );
352
#else
353
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
354
#endif
355
}
356

    
357
/*----------------------------------------------------------------------------
358
| Returns 1 if the extended double-precision floating-point value `a' is a
359
| signaling NaN; otherwise returns 0.
360
*----------------------------------------------------------------------------*/
361

    
362
int floatx80_is_signaling_nan( floatx80 a )
363
{
364
#if SNAN_BIT_IS_ONE
365
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
366
#else
367
    bits64 aLow;
368

    
369
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
370
    return
371
           ( ( a.high & 0x7FFF ) == 0x7FFF )
372
        && (bits64) ( aLow<<1 )
373
        && ( a.low == aLow );
374
#endif
375
}
376

    
377
/*----------------------------------------------------------------------------
378
| Returns the result of converting the extended double-precision floating-
379
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
380
| invalid exception is raised.
381
*----------------------------------------------------------------------------*/
382

    
383
static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
384
{
385
    commonNaNT z;
386

    
387
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
388
    z.sign = a.high>>15;
389
    z.low = 0;
390
    z.high = a.low;
391
    return z;
392
}
393

    
394
/*----------------------------------------------------------------------------
395
| Returns the result of converting the canonical NaN `a' to the extended
396
| double-precision floating-point format.
397
*----------------------------------------------------------------------------*/
398

    
399
static floatx80 commonNaNToFloatx80( commonNaNT a )
400
{
401
    floatx80 z;
402

    
403
    if (a.high)
404
        z.low = a.high;
405
    else
406
        z.low = floatx80_default_nan_low;
407
    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
408
    return z;
409
}
410

    
411
/*----------------------------------------------------------------------------
412
| Takes two extended double-precision floating-point values `a' and `b', one
413
| of which is a NaN, and returns the appropriate NaN result.  If either `a' or
414
| `b' is a signaling NaN, the invalid exception is raised.
415
*----------------------------------------------------------------------------*/
416

    
417
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
418
{
419
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
420

    
421
    if ( STATUS(default_nan_mode) ) {
422
        a.low = floatx80_default_nan_low;
423
        a.high = floatx80_default_nan_high;
424
        return a;
425
    }
426

    
427
    aIsNaN = floatx80_is_nan( a );
428
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
429
    bIsNaN = floatx80_is_nan( b );
430
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
431
#if SNAN_BIT_IS_ONE
432
    a.low &= ~LIT64( 0xC000000000000000 );
433
    b.low &= ~LIT64( 0xC000000000000000 );
434
#else
435
    a.low |= LIT64( 0xC000000000000000 );
436
    b.low |= LIT64( 0xC000000000000000 );
437
#endif
438
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
439
    if ( aIsSignalingNaN ) {
440
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
441
        return bIsNaN ? b : a;
442
    }
443
    else if ( aIsNaN ) {
444
        if ( bIsSignalingNaN || ! bIsNaN ) return a;
445
 returnLargerSignificand:
446
        if ( a.low < b.low ) return b;
447
        if ( b.low < a.low ) return a;
448
        return ( a.high < b.high ) ? a : b;
449
    }
450
    else {
451
        return b;
452
    }
453
}
454

    
455
#endif
456

    
457
#ifdef FLOAT128
458

    
459
/*----------------------------------------------------------------------------
460
| The pattern for a default generated quadruple-precision NaN.  The `high' and
461
| `low' values hold the most- and least-significant bits, respectively.
462
*----------------------------------------------------------------------------*/
463
#if SNAN_BIT_IS_ONE
464
#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
465
#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
466
#else
467
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
468
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
469
#endif
470

    
471
/*----------------------------------------------------------------------------
472
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
473
| NaN; otherwise returns 0.
474
*----------------------------------------------------------------------------*/
475

    
476
int float128_is_nan( float128 a )
477
{
478
#if SNAN_BIT_IS_ONE
479
    return
480
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
481
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
482
#else
483
    return
484
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
485
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
486
#endif
487
}
488

    
489
/*----------------------------------------------------------------------------
490
| Returns 1 if the quadruple-precision floating-point value `a' is a
491
| signaling NaN; otherwise returns 0.
492
*----------------------------------------------------------------------------*/
493

    
494
int float128_is_signaling_nan( float128 a )
495
{
496
#if SNAN_BIT_IS_ONE
497
    return
498
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
499
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
500
#else
501
    return
502
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
503
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
504
#endif
505
}
506

    
507
/*----------------------------------------------------------------------------
508
| Returns the result of converting the quadruple-precision floating-point NaN
509
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
510
| exception is raised.
511
*----------------------------------------------------------------------------*/
512

    
513
static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
514
{
515
    commonNaNT z;
516

    
517
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
518
    z.sign = a.high>>63;
519
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
520
    return z;
521
}
522

    
523
/*----------------------------------------------------------------------------
524
| Returns the result of converting the canonical NaN `a' to the quadruple-
525
| precision floating-point format.
526
*----------------------------------------------------------------------------*/
527

    
528
static float128 commonNaNToFloat128( commonNaNT a )
529
{
530
    float128 z;
531

    
532
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
533
    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
534
    return z;
535
}
536

    
537
/*----------------------------------------------------------------------------
538
| Takes two quadruple-precision floating-point values `a' and `b', one of
539
| which is a NaN, and returns the appropriate NaN result.  If either `a' or
540
| `b' is a signaling NaN, the invalid exception is raised.
541
*----------------------------------------------------------------------------*/
542

    
543
static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
544
{
545
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
546

    
547
    if ( STATUS(default_nan_mode) ) {
548
        a.low = float128_default_nan_low;
549
        a.high = float128_default_nan_high;
550
        return a;
551
    }
552

    
553
    aIsNaN = float128_is_nan( a );
554
    aIsSignalingNaN = float128_is_signaling_nan( a );
555
    bIsNaN = float128_is_nan( b );
556
    bIsSignalingNaN = float128_is_signaling_nan( b );
557
#if SNAN_BIT_IS_ONE
558
    a.high &= ~LIT64( 0x0000800000000000 );
559
    b.high &= ~LIT64( 0x0000800000000000 );
560
#else
561
    a.high |= LIT64( 0x0000800000000000 );
562
    b.high |= LIT64( 0x0000800000000000 );
563
#endif
564
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
565
    if ( aIsSignalingNaN ) {
566
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
567
        return bIsNaN ? b : a;
568
    }
569
    else if ( aIsNaN ) {
570
        if ( bIsSignalingNaN || ! bIsNaN ) return a;
571
 returnLargerSignificand:
572
        if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
573
        if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
574
        return ( a.high < b.high ) ? a : b;
575
    }
576
    else {
577
        return b;
578
    }
579
}
580

    
581
#endif