forked from microsoft/STL
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxdnorm.cpp
40 lines (34 loc) · 1.54 KB
/
xdnorm.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// _Dnorm function -- IEEE 754 version
#include "xmath.h"
_EXTERN_C_UNLESS_PURE
short _Dnorm(_Dval* ps) { // normalize double fraction
short xchar;
unsigned short sign = (unsigned short) (ps->_Sh[_D0] & _DSIGN);
xchar = 1;
if ((ps->_Sh[_D0] &= _DFRAC) != 0 || ps->_Sh[_D1] || ps->_Sh[_D2] || ps->_Sh[_D3]) { // nonzero, scale
for (; ps->_Sh[_D0] == 0; xchar -= 16) { // shift left by 16
ps->_Sh[_D0] = ps->_Sh[_D1];
ps->_Sh[_D1] = ps->_Sh[_D2];
ps->_Sh[_D2] = ps->_Sh[_D3];
ps->_Sh[_D3] = 0;
}
for (; ps->_Sh[_D0] < 1 << _DOFF; --xchar) { // shift left by 1
ps->_Sh[_D0] = (unsigned short) (ps->_Sh[_D0] << 1 | ps->_Sh[_D1] >> 15);
ps->_Sh[_D1] = (unsigned short) (ps->_Sh[_D1] << 1 | ps->_Sh[_D2] >> 15);
ps->_Sh[_D2] = (unsigned short) (ps->_Sh[_D2] << 1 | ps->_Sh[_D3] >> 15);
ps->_Sh[_D3] <<= 1;
}
for (; 1 << (_DOFF + 1) <= ps->_Sh[_D0]; ++xchar) { // shift right by 1
ps->_Sh[_D3] = (unsigned short) (ps->_Sh[_D3] >> 1 | ps->_Sh[_D2] << 15);
ps->_Sh[_D2] = (unsigned short) (ps->_Sh[_D2] >> 1 | ps->_Sh[_D1] << 15);
ps->_Sh[_D1] = (unsigned short) (ps->_Sh[_D1] >> 1 | ps->_Sh[_D0] << 15);
ps->_Sh[_D0] >>= 1;
}
ps->_Sh[_D0] &= _DFRAC;
}
ps->_Sh[_D0] |= sign;
return xchar;
}
_END_EXTERN_C_UNLESS_PURE