MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / decCanonical

Function decCanonical

extern/decNumber/decBasic.c:75–149  ·  view source on GitHub ↗

------------------------------------------------------------------ */ decCanonical -- copy a decFloat, making canonical */ / result gets the canonicalized df */ df is the decFloat to copy and make canonical */ returns result */ / This is exposed via decFloatCanonical for Double and

Source from the content-addressed store, hash-verified

73/* This works on specials, too; no error or exception is possible. */
74/* ------------------------------------------------------------------ */
75static decFloat * decCanonical(decFloat *result, const decFloat *df) {
76 uInt encode, precode, dpd; // work
77 uInt inword, uoff, canon; // ..
78 Int n; // counter (down)
79 if (df!=result) *result=*df; // effect copy if needed
80 if (DFISSPECIAL(result)) {
81 if (DFISINF(result)) return decInfinity(result, df); // clean Infinity
82 // is a NaN
83 DFWORD(result, 0)&=~ECONNANMASK; // clear ECON except selector
84 if (DFISCCZERO(df)) return result; // coefficient continuation is 0
85 // drop through to check payload
86 }
87 // return quickly if the coefficient continuation is canonical
88 { // declare block
89 #if DOUBLE
90 uInt sourhi=DFWORD(df, 0);
91 uInt sourlo=DFWORD(df, 1);
92 if (CANONDPDOFF(sourhi, 8)
93 && CANONDPDTWO(sourhi, sourlo, 30)
94 && CANONDPDOFF(sourlo, 20)
95 && CANONDPDOFF(sourlo, 10)
96 && CANONDPDOFF(sourlo, 0)) return result;
97 #elif QUAD
98 uInt sourhi=DFWORD(df, 0);
99 uInt sourmh=DFWORD(df, 1);
100 uInt sourml=DFWORD(df, 2);
101 uInt sourlo=DFWORD(df, 3);
102 if (CANONDPDOFF(sourhi, 4)
103 && CANONDPDTWO(sourhi, sourmh, 26)
104 && CANONDPDOFF(sourmh, 16)
105 && CANONDPDOFF(sourmh, 6)
106 && CANONDPDTWO(sourmh, sourml, 28)
107 && CANONDPDOFF(sourml, 18)
108 && CANONDPDOFF(sourml, 8)
109 && CANONDPDTWO(sourml, sourlo, 30)
110 && CANONDPDOFF(sourlo, 20)
111 && CANONDPDOFF(sourlo, 10)
112 && CANONDPDOFF(sourlo, 0)) return result;
113 #endif
114 } // block
115
116 // Loop to repair a non-canonical coefficent, as needed
117 inword=DECWORDS-1; // current input word
118 uoff=0; // bit offset of declet
119 encode=DFWORD(result, inword);
120 for (n=DECLETS-1; n>=0; n--) { // count down declets of 10 bits
121 dpd=encode>>uoff;
122 uoff+=10;
123 if (uoff>32) { // crossed uInt boundary
124 inword--;
125 encode=DFWORD(result, inword);
126 uoff-=32;
127 dpd|=encode<<(10-uoff); // get pending bits
128 }
129 dpd&=0x3ff; // clear uninteresting bits
130 if (dpd<0x16e) continue; // must be canonical
131 canon=BIN2DPD[DPD2BIN[dpd]]; // determine canonical declet
132 if (canon==dpd) continue; // have canonical declet

Callers 15

decDivideFunction · 0.85
decFloatAbsFunction · 0.85
decFloatAddFunction · 0.85
decFloatCanonicalFunction · 0.85
decFloatMaxFunction · 0.85
decFloatMaxMagFunction · 0.85
decFloatMinFunction · 0.85
decFloatMinMagFunction · 0.85
decFloatMinusFunction · 0.85
decFloatPlusFunction · 0.85
decFloatQuantizeFunction · 0.85
decFloatRotateFunction · 0.85

Calls 1

decInfinityFunction · 0.85

Tested by

no test coverage detected