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. */
| 1150 | and nanoseconds. |
| 1151 | */ |
| 1152 | int 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 |
no test coverage detected