| 1063 | } |
| 1064 | |
| 1065 | int decimal2longlong(decimal_t *from, longlong *to) |
| 1066 | { |
| 1067 | dec1 *buf=from->buf; |
| 1068 | longlong x=0; |
| 1069 | int intg, frac; |
| 1070 | |
| 1071 | for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1) |
| 1072 | { |
| 1073 | longlong y=x; |
| 1074 | /* |
| 1075 | Attention: trick! |
| 1076 | we're calculating -|from| instead of |from| here |
| 1077 | because |LONGLONG_MIN| > LONGLONG_MAX |
| 1078 | so we can convert -9223372036854775808 correctly |
| 1079 | */ |
| 1080 | x=x*DIG_BASE - *buf++; |
| 1081 | if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y)) |
| 1082 | { |
| 1083 | /* |
| 1084 | the decimal is bigger than any possible integer |
| 1085 | return border integer depending on the sign |
| 1086 | */ |
| 1087 | *to= from->sign ? LONGLONG_MIN : LONGLONG_MAX; |
| 1088 | return E_DEC_OVERFLOW; |
| 1089 | } |
| 1090 | } |
| 1091 | /* boundary case: 9223372036854775808 */ |
| 1092 | if (unlikely(from->sign==0 && x == LONGLONG_MIN)) |
| 1093 | { |
| 1094 | *to= LONGLONG_MAX; |
| 1095 | return E_DEC_OVERFLOW; |
| 1096 | } |
| 1097 | |
| 1098 | *to=from->sign ? x : -x; |
| 1099 | for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1) |
| 1100 | if (*buf++) |
| 1101 | return E_DEC_TRUNCATED; |
| 1102 | return E_DEC_OK; |
| 1103 | } |
| 1104 | |
| 1105 | |
| 1106 | #define LLDIV_MIN -1000000000000000000LL |