PostGIS  3.1.6dev-r@@SVN_REVISION@@

◆ test_lwprint()

static void test_lwprint ( void  )
static

Definition at line 274 of file cu_print.c.

275 {
276  static const int precision_start = -1; /* Check for negatives */
277  static const int precision_end = OUT_MAX_DIGITS + 2; /* Ask for more digits than available in all cases */
278 
279  /* Negative zero should be printed as 0 */
280  for (int i = precision_start; i < precision_end; i++)
281  assert_lwprint_equal(-0, i, "0");
282 
283  /* 2 = 0x4000000000000000
284  * -2 = 0xC000000000000000
285  * Both with exact representation, so we should never see extra digits
286  */
287  for (int i = precision_start; i < precision_end; i++)
288  {
289  assert_lwprint_equal(2.0, i, "2");
290  assert_lwprint_equal(-2.0, i, "-2");
291  }
292 
293  /* 0.3 doesn't have an exact representation but it's the shortest representation for 0x3FD3333333333333
294  * 2.99999999999999988897769753748E-1 = 0x3FD3333333333333
295  */
296  assert_lwprint_equal(0.3, 0, "0");
297  for (int i = 1; i < precision_end; i++)
298  {
299  assert_lwprint_equal(0.3, i, "0.3");
300  assert_lwprint_equal(2.99999999999999988897769753748E-1, i, "0.3");
301  }
302 
303  /* 2.5 has an exact representation (0x4004000000000000) */
304  assert_lwprint_equal(2.5, 0, "2");
305  for (int i = 1; i < precision_end; i++)
306  {
307  assert_lwprint_equal(2.5, i, "2.5");
308  }
309 
310  /* Test trailing zeros and rounding
311  * 0.0000000298023223876953125 == 0x3E60000000000000 == 2.98023223876953125E-8
312  */
313  assert_lwprint_equal(0.0000000298023223876953125, -1, "0");
314  assert_lwprint_equal(0.0000000298023223876953125, 0, "0");
315  assert_lwprint_equal(0.0000000298023223876953125, 1, "0");
316  assert_lwprint_equal(0.0000000298023223876953125, 2, "0");
317  assert_lwprint_equal(0.0000000298023223876953125, 3, "0");
318  assert_lwprint_equal(0.0000000298023223876953125, 4, "0");
319  assert_lwprint_equal(0.0000000298023223876953125, 5, "0");
320  assert_lwprint_equal(0.0000000298023223876953125, 6, "0");
321  assert_lwprint_equal(0.0000000298023223876953125, 7, "0");
322  assert_lwprint_equal(0.0000000298023223876953125, 8, "0.00000003");
323  assert_lwprint_equal(0.0000000298023223876953125, 9, "0.00000003");
324  assert_lwprint_equal(0.0000000298023223876953125, 10, "0.0000000298");
325  assert_lwprint_equal(0.0000000298023223876953125, 11, "0.0000000298");
326  assert_lwprint_equal(0.0000000298023223876953125, 12, "0.000000029802");
327  assert_lwprint_equal(0.0000000298023223876953125, 13, "0.0000000298023");
328  assert_lwprint_equal(0.0000000298023223876953125, 14, "0.00000002980232");
329  assert_lwprint_equal(0.0000000298023223876953125, 15, "0.000000029802322");
330  assert_lwprint_equal(0.0000000298023223876953125, 16, "0.0000000298023224");
331  assert_lwprint_equal(0.0000000298023223876953125, 17, "0.00000002980232239");
332  assert_lwprint_equal(0.0000000298023223876953125, 18, "0.000000029802322388");
333  assert_lwprint_equal(0.0000000298023223876953125, 19, "0.0000000298023223877");
334  assert_lwprint_equal(0.0000000298023223876953125, 20, "0.0000000298023223877");
335  assert_lwprint_equal(0.0000000298023223876953125, 21, "0.000000029802322387695");
336  assert_lwprint_equal(0.0000000298023223876953125, 22, "0.0000000298023223876953");
337  assert_lwprint_equal(0.0000000298023223876953125, 23, "0.00000002980232238769531");
338  assert_lwprint_equal(0.0000000298023223876953125, 24, "0.000000029802322387695312");
339  assert_lwprint_equal(0.0000000298023223876953125, 40, "0.000000029802322387695312");
340 
341  /* Negative 0 after rounding should be printed as 0 */
342  assert_lwprint_equal(-0.0005, 0, "0");
343  assert_lwprint_equal(-0.0005, 1, "0");
344  assert_lwprint_equal(-0.0005, 2, "0");
345  assert_lwprint_equal(-0.0005, 3, "0");
346  assert_lwprint_equal(-0.0005, 4, "-0.0005");
347 
348  /* Rounding on the first decimal digit */
349  assert_lwprint_equal(-2.5, 0, "-2");
350  assert_lwprint_equal(-1.5, 0, "-2");
351  assert_lwprint_equal(-0.99, 0, "-1");
352  assert_lwprint_equal(-0.5, 0, "0");
353  assert_lwprint_equal(-0.01, 0, "0");
354  assert_lwprint_equal(0.5, 0, "0");
355  assert_lwprint_equal(0.99, 0, "1");
356  assert_lwprint_equal(1.5, 0, "2");
357  assert_lwprint_equal(2.5, 0, "2");
358 
359  /* Check rounding */
360  assert_lwprint_equal(0.035, 2, "0.04");
361  assert_lwprint_equal(0.045, 2, "0.04");
362  assert_lwprint_equal(0.04500000000000001, 2, "0.05");
363  assert_lwprint_equal(0.077, 2, "0.08");
364  assert_lwprint_equal(0.087, 2, "0.09");
365  assert_lwprint_equal(1.05, 1, "1");
366  assert_lwprint_equal(1.005, 2, "1");
367  assert_lwprint_equal(2.05, 1, "2");
368  assert_lwprint_equal(2.005, 2, "2");
369 
370  for (int i = 0; i < 15; i++)
371  assert_lwprint_equal(-0.99999999999999988898, i, "-1");
372  for (int i = 15; i < 20; i++)
373  assert_lwprint_equal(-0.99999999999999988898, i, "-0.9999999999999999");
374 
375  for (int i = 0; i < 16; i++)
376  assert_lwprint_equal(0.99999999999999977796, i, "1");
377  for (int i = 16; i < 20; i++)
378  assert_lwprint_equal(0.99999999999999977796, i, "0.9999999999999998");
379 
380  assert_lwprint_equal(0.0999999999999999916733273153113, 0, "0");
381  assert_lwprint_equal(-0.0999999999999999916733273153113, 0, "0");
382  for (int i = 1; i < 15; i++)
383  {
384  assert_lwprint_equal(0.0999999999999999916733273153113, i, "0.1");
385  assert_lwprint_equal(-0.0999999999999999916733273153113, i, "-0.1");
386  }
387 
388  assert_lwprint_equal(0.00999999999999999847, 0, "0");
389  assert_lwprint_equal(-0.00999999999999999847, 0, "0");
390  assert_lwprint_equal(0.00999999999999999847, 1, "0");
391  assert_lwprint_equal(-0.00999999999999999847, 1, "0");
392  for (int i = 2; i < 15; i++)
393  {
394  assert_lwprint_equal(0.00999999999999999847, i, "0.01");
395  assert_lwprint_equal(-0.00999999999999999847, i, "-0.01");
396  }
397 
398  /* Test regression changes (output that changed in the tests vs 3.0) */
399  /* There is at most 17 significative digits */
400  assert_lwprint_equal(-123456789012345.12345678, 20, "-123456789012345.12");
401  assert_lwprint_equal(123456789012345.12345678, 20, "123456789012345.12");
402 
403  /* Precision is respected (as number of decimal digits) */
404  assert_lwprint_equal(92115.51207431706, 12, "92115.51207431706");
405  assert_lwprint_equal(463412.82600000006, 12, "463412.82600000006");
406  assert_lwprint_equal(463462.2069374289, 12, "463462.2069374289");
407  assert_lwprint_equal(-115.17281600000001, OUT_DEFAULT_DECIMAL_DIGITS, "-115.17281600000001");
408  assert_lwprint_equal(-115.17281600000001, 12, "-115.172816");
409  assert_lwprint_equal(36.11464599999999, OUT_DEFAULT_DECIMAL_DIGITS, "36.11464599999999");
410  assert_lwprint_equal(36.11464599999999, 12, "36.114646");
411  assert_lwprint_equal(400000, 0, "400000");
412  assert_lwprint_equal(400000, 12, "400000");
413  assert_lwprint_equal(400000, 20, "400000");
414  assert_lwprint_equal(5.0833333333333330372738600999582558870316, 15, "5.083333333333333");
415  assert_lwprint_equal(1.4142135623730951, 15, "1.414213562373095");
416  assert_lwprint_equal(143.62025166838282, 15, "143.62025166838282");
417  assert_lwprint_equal(-30.037497356076827, 15, "-30.037497356076827");
418  assert_lwprint_equal(142.92857147299705, 15, "142.92857147299705");
419  assert_lwprint_equal(-32.75101196874403, 15, "-32.75101196874403");
420 
421  /* Note about this:
422  * 149.57565307617187 == 0x4062B26BC0000000
423  * 149.57565307617188 == 0x4062B26BC0000000
424  *
425  * 0x4062B26BC0000000 == 149.575653076171875
426  * Both if we consider "round to nearest, ties to even" (which is what we use)
427  * or "round to nearest, ties away from zero":
428  * 75 => 80 => 8 for the last digit
429  *
430  * It acts the same way in PostgreSQL:
431  # Select '149.57565307617187'::float8, '149.575653076171875'::float8, '149.57565307617188'::float8;
432  float8 | float8 | float8
433  --------------------+--------------------+--------------------
434  149.57565307617188 | 149.57565307617188 | 149.57565307617188
435  (1 row)
436  */
437  assert_lwprint_equal(149.57565307617187, 15, "149.57565307617188");
438  assert_lwprint_equal(-149.57565307617187, 15, "-149.57565307617188");
439 
440  /* Shortest representation is used */
441  assert_lwprint_equal(7000109.9999999990686774253845214843750000000000, 8, "7000110");
442  assert_lwprint_equal(7000109.9999999990686774253845214843750000000000, 12, "7000109.999999999");
443 
444  /* SnapToGrid by itself is not enough to limit output decimals */
445  const double d = 526355.92112222222;
446  const double gridsize = 0.00001;
447  const double gridded = rint(d / gridsize) * gridsize; /* Formula from ptarray_grid_in_place */
448  assert_lwprint_equal(gridded, 15, "526355.9211200001");
449  assert_lwprint_equal(gridded, 5, "526355.92112");
450 
451  /* Test the change towards scientific notation */
452  assert_lwprint_equal(nextafter(OUT_MAX_DOUBLE, 0), OUT_MAX_DIGITS, "999999999999999.9");
453  assert_lwprint_equal(nextafter(-OUT_MAX_DOUBLE, 0), OUT_MAX_DIGITS, "-999999999999999.9");
456  assert_lwprint_equal(nextafter(OUT_MAX_DOUBLE, INFINITY), OUT_MAX_DIGITS, "1.0000000000000001e+15");
457  assert_lwprint_equal(nextafter(-OUT_MAX_DOUBLE, -INFINITY), OUT_MAX_DIGITS, "-1.0000000000000001e+15");
458 
459  assert_lwprint_equal(nextafter(OUT_MIN_DOUBLE, 0), OUT_MAX_DIGITS, "9.999999999999999e-9");
460  assert_lwprint_equal(nextafter(-OUT_MIN_DOUBLE, 0), OUT_MAX_DIGITS, "-9.999999999999999e-9");
463  assert_lwprint_equal(nextafter(OUT_MIN_DOUBLE, INFINITY), OUT_MAX_DIGITS, "0.000000010000000000000002");
464  assert_lwprint_equal(nextafter(-OUT_MIN_DOUBLE, -INFINITY), OUT_MAX_DIGITS, "-0.000000010000000000000002");
465 
466 
467  /* Big numbers that use scientific notation respect the precision parameter */
468  assert_lwprint_equal(9e+300, 0, "9e+300");
469  assert_lwprint_equal(9e+300, 15, "9e+300");
470  assert_lwprint_equal(-9e+300, 0, "-9e+300");
471  assert_lwprint_equal(-9e+300, 15, "-9e+300");
472  assert_lwprint_equal(9.000000000000001e+300, 0, "9e+300");
473  assert_lwprint_equal(9.000000000000001e+300, 15, "9.000000000000001e+300");
474  assert_lwprint_equal(-9.000000000000001e+300, 0, "-9e+300");
475  assert_lwprint_equal(-9.000000000000001e+300, 15, "-9.000000000000001e+300");
476 
477  assert_lwprint_equal(6917529027641081856.0, 17, "6.917529027641082e+18");
478  assert_lwprint_equal(6917529027641081856.0, 16, "6.917529027641082e+18");
479  assert_lwprint_equal(6917529027641081856.0, 15, "6.917529027641082e+18");
480  assert_lwprint_equal(6917529027641081856.0, 14, "6.91752902764108e+18");
481  assert_lwprint_equal(6917529027641081856.0, 13, "6.9175290276411e+18");
482  assert_lwprint_equal(6917529027641081856.0, 12, "6.917529027641e+18");
483  assert_lwprint_equal(6917529027641081856.0, 11, "6.91752902764e+18");
484  assert_lwprint_equal(6917529027641081856.0, 10, "6.9175290276e+18");
485  assert_lwprint_equal(6917529027641081856.0, 9, "6.917529028e+18");
486  assert_lwprint_equal(6917529027641081856.0, 8, "6.91752903e+18");
487  assert_lwprint_equal(6917529027641081856.0, 7, "6.917529e+18");
488  assert_lwprint_equal(6917529027641081856.0, 6, "6.917529e+18");
489  assert_lwprint_equal(6917529027641081856.0, 5, "6.91753e+18");
490  assert_lwprint_equal(6917529027641081856.0, 4, "6.9175e+18");
491  assert_lwprint_equal(6917529027641081856.0, 3, "6.918e+18");
492  assert_lwprint_equal(6917529027641081856.0, 2, "6.92e+18");
493  assert_lwprint_equal(6917529027641081856.0, 1, "6.9e+18");
494  assert_lwprint_equal(6917529027641081856.0, 0, "7e+18");
495 
496  /* Test special values (+-inf, NaNs) */
497  for (int i = precision_start; i < precision_end; i++)
498  {
499  assert_lwprint_equal(NAN, i, "NaN");
500  assert_lwprint_equal(INFINITY, i, "Infinity");
501  assert_lwprint_equal(-INFINITY, i, "-Infinity");
502  }
503 
504  /* Extremes */
505  assert_lwprint_equal(2.2250738585072014e-308, OUT_MAX_DIGITS, "2.2250738585072014e-308");
506  assert_lwprint_equal(1.7976931348623157e+308, OUT_MAX_DIGITS, "1.7976931348623157e+308"); /* Max */
507  assert_lwprint_equal(2.9802322387695312E-8, OUT_MAX_DIGITS, "0.000000029802322387695312"); /* Trailing zeros */
508 }
#define assert_lwprint_equal(d, precision, expected)
Definition: cu_print.c:269
#define OUT_MAX_DIGITS
#define OUT_DEFAULT_DECIMAL_DIGITS
#define OUT_MAX_DOUBLE
#define OUT_MIN_DOUBLE
#define NAN
Definition: lwgeodetic.h:37

References assert_lwprint_equal, NAN, OUT_DEFAULT_DECIMAL_DIGITS, OUT_MAX_DIGITS, OUT_MAX_DOUBLE, and OUT_MIN_DOUBLE.

Referenced by print_suite_setup().

Here is the caller graph for this function: