| 247 | |
| 248 | |
| 249 | static void float_to_text(const dsc* from, dsc* to, Callbacks* cb) |
| 250 | { |
| 251 | /************************************** |
| 252 | * |
| 253 | * f l o a t _ t o _ t e x t |
| 254 | * |
| 255 | ************************************** |
| 256 | * |
| 257 | * Functional description |
| 258 | * Convert an arbitrary floating type number to text. |
| 259 | * To avoid messiness, convert first into a temp (fixed) then |
| 260 | * move to the destination. |
| 261 | * Never print more digits than the source type can actually |
| 262 | * provide: instead pad the output with blanks on the right if |
| 263 | * needed. |
| 264 | * |
| 265 | **************************************/ |
| 266 | double d; |
| 267 | char temp[] = "-1.234567890123456E-300"; |
| 268 | |
| 269 | const int to_len = DSC_string_length(to); // length of destination |
| 270 | const int width = MIN(to_len, (int) sizeof(temp) - 1); // minimum width to print |
| 271 | |
| 272 | int precision; |
| 273 | if (dtype_double == from->dsc_dtype) |
| 274 | { |
| 275 | precision = 16; // minimum significant digits in a double |
| 276 | d = *(double*) from->dsc_address; |
| 277 | } |
| 278 | else |
| 279 | { |
| 280 | fb_assert(dtype_real == from->dsc_dtype); |
| 281 | precision = 8; // minimum significant digits in a float |
| 282 | d = (double) *(float*) from->dsc_address; |
| 283 | } |
| 284 | |
| 285 | // If this is a double with non-zero scale, then it is an old-style |
| 286 | // NUMERIC(15, -scale): print it in fixed format with -scale digits |
| 287 | // to the right of the ".". |
| 288 | |
| 289 | // CVC: Here sprintf was given an extra space in the two formatting |
| 290 | // masks used below, "%- #*.*f" and "%- #*.*g" but certainly with positive |
| 291 | // quantities and CAST it yields an annoying leading space. |
| 292 | // However, by getting rid of the space you get in dialect 1: |
| 293 | // cast(17/13 as char(5)) => 1.308 |
| 294 | // cast(-17/13 as char(5)) => -1.31 |
| 295 | // Since this is inconsistent with dialect 3, see workaround at the tail |
| 296 | // of this function. |
| 297 | |
| 298 | int chars_printed; // number of characters printed |
| 299 | if ((dtype_double == from->dsc_dtype) && (from->dsc_scale < 0)) |
| 300 | { |
| 301 | chars_printed = fb_utils::snprintf(temp, sizeof(temp), "%- #*.*f", width, -from->dsc_scale, d); |
| 302 | if (chars_printed <= 0 || chars_printed > width) |
| 303 | chars_printed = -1; |
| 304 | } |
| 305 | else |
| 306 | chars_printed = -1; |
no test coverage detected