| 1120 | |
| 1121 | |
| 1122 | void exactNumericToStr(SINT64 value, int scale, Firebird::string& target, bool append) |
| 1123 | { |
| 1124 | if (value == 0) |
| 1125 | { |
| 1126 | if (append) |
| 1127 | target.append("0", 1); |
| 1128 | else |
| 1129 | target.assign("0", 1); |
| 1130 | return; |
| 1131 | } |
| 1132 | |
| 1133 | const int MAX_SCALE = 25; |
| 1134 | const int MAX_BUFFER = 50; |
| 1135 | |
| 1136 | if (scale < -MAX_SCALE || scale > MAX_SCALE) |
| 1137 | { |
| 1138 | fb_assert(false); |
| 1139 | return; // throw exception here? |
| 1140 | } |
| 1141 | |
| 1142 | const bool neg = value < 0; |
| 1143 | const bool dot = scale < 0; // Need the decimal separator or not? |
| 1144 | char buffer[MAX_BUFFER]; |
| 1145 | int iter = MAX_BUFFER; |
| 1146 | |
| 1147 | buffer[--iter] = '\0'; |
| 1148 | |
| 1149 | if (scale > 0) |
| 1150 | { |
| 1151 | while (scale-- > 0) |
| 1152 | buffer[--iter] = '0'; |
| 1153 | } |
| 1154 | |
| 1155 | bool dot_used = false; |
| 1156 | FB_UINT64 uval = neg ? FB_UINT64(-(value + 1)) + 1 : value; // avoid problems with MIN_SINT64 |
| 1157 | |
| 1158 | while (uval != 0) |
| 1159 | { |
| 1160 | buffer[--iter] = static_cast<char>(uval % 10) + '0'; |
| 1161 | uval /= 10; |
| 1162 | |
| 1163 | if (dot && !++scale) |
| 1164 | { |
| 1165 | buffer[--iter] = '.'; |
| 1166 | dot_used = true; |
| 1167 | } |
| 1168 | } |
| 1169 | |
| 1170 | if (dot) |
| 1171 | { |
| 1172 | // if scale > 0 we have N.M |
| 1173 | // if scale == 0 we have .M and we need 0.M |
| 1174 | // if scale < 0 we have pending zeroes and need 0.{0+}M |
| 1175 | if (!dot_used) |
| 1176 | { |
| 1177 | while (scale++ < 0) |
| 1178 | buffer[--iter] = '0'; |
| 1179 |
no test coverage detected