MCPcopy Create free account
hub / github.com/Meituan-Dianping/SQLAdvisor / double2lldiv_t

Function double2lldiv_t

strings/decimal.c:1152–1182  ·  view source on GitHub ↗

Convert double value to lldiv_t valie. @param from The double value to convert from. @param OUT to The lldit_t variable to convert to. @return 0 on success, error code on error. Integer part goes into lld.quot. Fractional part multiplied to 1000000000 (10^9) goes to lld.rem. Typically used in datetime calculations to split seconds and nanoseconds. */

Source from the content-addressed store, hash-verified

1150 and nanoseconds.
1151*/
1152int double2lldiv_t(double nr, lldiv_t *lld)
1153{
1154 if (nr > LLDIV_MAX)
1155 {
1156 lld->quot= LLDIV_MAX;
1157 lld->rem= 0;
1158 return E_DEC_OVERFLOW;
1159 }
1160 else if (nr < LLDIV_MIN)
1161 {
1162 lld->quot= LLDIV_MIN;
1163 lld->rem= 0;
1164 return E_DEC_OVERFLOW;
1165 }
1166 /* Truncate fractional part toward zero and store into "quot" */
1167 lld->quot= (longlong) (nr > 0 ? floor(nr) : ceil(nr));
1168 /* Multiply reminder to 10^9 and store into "rem" */
1169 lld->rem= (longlong) rint((nr - (double) lld->quot) * 1000000000);
1170 /*
1171 Sometimes the expression "(double) 0.999999999xxx * (double) 10e9"
1172 gives 1,000,000,000 instead of 999,999,999 due to lack of double precision.
1173 The callers do not expect lld->rem to be greater than 999,999,999.
1174 Let's catch this corner case and put the "nanounit" (e.g. nanosecond)
1175 value in ldd->rem back into the valid range.
1176 */
1177 if (lld->rem > 999999999LL)
1178 lld->rem= 999999999LL;
1179 else if (lld->rem < -999999999LL)
1180 lld->rem= -999999999LL;
1181 return E_DEC_OK;
1182}
1183
1184
1185

Callers 2

Calls 1

rintFunction · 0.85

Tested by

no test coverage detected