PostGIS  3.1.6dev-r@@SVN_REVISION@@
cu_print.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  * Copyright 2008 Paul Ramsey
6  *
7  * This is free software; you can redistribute and/or modify it under
8  * the terms of the GNU General Public Licence. See the COPYING file.
9  *
10  **********************************************************************/
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include "CUnit/Basic.h"
16 
17 #include "liblwgeom_internal.h"
18 #include "cu_tester.h"
19 
20 static void
21 test_lwpoint_to_latlon_assert_format(char *point_wkt, const char *format, const char *expected)
22 {
23  LWPOINT * test_point = (LWPOINT*)lwgeom_from_wkt(point_wkt, LW_PARSER_CHECK_NONE);
24  int num_old_failures, num_new_failures;
25  char * actual;
27  actual = lwpoint_to_latlon(test_point, format);
28  if (0 != strlen(cu_error_msg))
29  {
30  printf("\nAssert failed:\n\tFormat [%s] generated an error: %s\n", format, cu_error_msg);
31  CU_FAIL();
32  }
33  num_old_failures = CU_get_number_of_failures();
34  CU_ASSERT_STRING_EQUAL(actual, expected);
35  num_new_failures = CU_get_number_of_failures();
36  if (num_new_failures > num_old_failures)
37  {
38  printf("\nAssert failed:\n\t%s\t(actual)\n\t%s\t(expected)\n", actual, expected);
39  }
40  lwfree(actual);
41  lwpoint_free(test_point);
42 }
43 static void
44 test_lwpoint_to_latlon_assert_error(char *point_wkt, const char *format)
45 {
46  LWPOINT * test_point = (LWPOINT*)lwgeom_from_wkt(point_wkt, LW_PARSER_CHECK_NONE);
48  char* tmp = lwpoint_to_latlon(test_point, format);
49  lwfree(tmp);
50  if (0 == strlen(cu_error_msg))
51  {
52  printf("\nAssert failed:\n\tFormat [%s] did not generate an error.\n", format);
53  CU_FAIL();
54  }
55  else
56  {
58  }
59  lwpoint_free(test_point);
60 }
61 
62 /*
63 ** Test points around the globe using the default format. Null and empty string both mean use the default.
64 */
65 static void
67 {
69  NULL,
70  "0\xC2\xB0"
71  "0'0.000\"N 0\xC2\xB0"
72  "0'0.000\"E");
73  test_lwpoint_to_latlon_assert_format("POINT(45.4545 12.34567)",
74  "",
75  "12\xC2\xB0"
76  "20'44.412\"N 45\xC2\xB0"
77  "27'16.200\"E");
79  NULL,
80  "90\xC2\xB0"
81  "0'0.000\"N 180\xC2\xB0"
82  "0'0.000\"E");
84  "",
85  "89\xC2\xB0"
86  "0'0.000\"N 1\xC2\xB0"
87  "0'0.000\"E");
88  test_lwpoint_to_latlon_assert_format("POINT(180.0001 90.0001)",
89  NULL,
90  "89\xC2\xB0"
91  "59'59.640\"N 0\xC2\xB0"
92  "0'0.360\"E");
93  test_lwpoint_to_latlon_assert_format("POINT(45.4545 -12.34567)",
94  "",
95  "12\xC2\xB0"
96  "20'44.412\"S 45\xC2\xB0"
97  "27'16.200\"E");
98  test_lwpoint_to_latlon_assert_format("POINT(180 -90)",
99  NULL,
100  "90\xC2\xB0"
101  "0'0.000\"S 180\xC2\xB0"
102  "0'0.000\"E");
103  test_lwpoint_to_latlon_assert_format("POINT(181 -91)",
104  "",
105  "89\xC2\xB0"
106  "0'0.000\"S 1\xC2\xB0"
107  "0'0.000\"E");
108  test_lwpoint_to_latlon_assert_format("POINT(180.0001 -90.0001)",
109  NULL,
110  "89\xC2\xB0"
111  "59'59.640\"S 0\xC2\xB0"
112  "0'0.360\"E");
113  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 12.34567)",
114  "",
115  "12\xC2\xB0"
116  "20'44.412\"N 45\xC2\xB0"
117  "27'16.200\"W");
118  test_lwpoint_to_latlon_assert_format("POINT(-180 90)",
119  NULL,
120  "90\xC2\xB0"
121  "0'0.000\"N 180\xC2\xB0"
122  "0'0.000\"W");
123  test_lwpoint_to_latlon_assert_format("POINT(-181 91)",
124  "",
125  "89\xC2\xB0"
126  "0'0.000\"N 1\xC2\xB0"
127  "0'0.000\"W");
128  test_lwpoint_to_latlon_assert_format("POINT(-180.0001 90.0001)",
129  NULL,
130  "89\xC2\xB0"
131  "59'59.640\"N 0\xC2\xB0"
132  "0'0.360\"W");
133  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)",
134  "",
135  "12\xC2\xB0"
136  "20'44.412\"S 45\xC2\xB0"
137  "27'16.200\"W");
138  test_lwpoint_to_latlon_assert_format("POINT(-180 -90)",
139  NULL,
140  "90\xC2\xB0"
141  "0'0.000\"S 180\xC2\xB0"
142  "0'0.000\"W");
143  test_lwpoint_to_latlon_assert_format("POINT(-181 -91)",
144  "",
145  "89\xC2\xB0"
146  "0'0.000\"S 1\xC2\xB0"
147  "0'0.000\"W");
148  test_lwpoint_to_latlon_assert_format("POINT(-180.0001 -90.0001)",
149  NULL,
150  "89\xC2\xB0"
151  "59'59.640\"S 0\xC2\xB0"
152  "0'0.360\"W");
153  test_lwpoint_to_latlon_assert_format("POINT(-2348982391.123456 -238749827.34879)",
154  "",
155  "12\xC2\xB0"
156  "39'4.356\"N 31\xC2\xB0"
157  "7'24.442\"W");
158  /* See https://trac.osgeo.org/postgis/ticket/3688 */
159  test_lwpoint_to_latlon_assert_format("POINT (76.6 -76.6)",
160  NULL,
161  "76\xC2\xB0"
162  "36'0.000\"S 76\xC2\xB0"
163  "36'0.000\"E");
164 }
165 
166 /*
167  * Test all possible combinations of the orders of the parameters.
168  */
169 static void
171 {
172  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "C DD MM SS", "S 12 20 44 W 45 27 16");
173  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "C DD SS MM", "S 12 44 20 W 45 16 27");
174  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "C MM DD SS", "S 20 12 44 W 27 45 16");
175  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "C MM SS DD", "S 20 44 12 W 27 16 45");
176  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "C SS DD MM", "S 44 12 20 W 16 45 27");
177  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "C SS MM DD", "S 44 20 12 W 16 27 45");
178 
179  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD C MM SS", "12 S 20 44 45 W 27 16");
180  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD C SS MM", "12 S 44 20 45 W 16 27");
181  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "MM C DD SS", "20 S 12 44 27 W 45 16");
182  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "MM C SS DD", "20 S 44 12 27 W 16 45");
183  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "SS C DD MM", "44 S 12 20 16 W 45 27");
184  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "SS C MM DD", "44 S 20 12 16 W 27 45");
185 
186  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD MM C SS", "12 20 S 44 45 27 W 16");
187  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD SS C MM", "12 44 S 20 45 16 W 27");
188  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "MM DD C SS", "20 12 S 44 27 45 W 16");
189  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "MM SS C DD", "20 44 S 12 27 16 W 45");
190  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "SS DD C MM", "44 12 S 20 16 45 W 27");
191  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "SS MM C DD", "44 20 S 12 16 27 W 45");
192 
193  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD MM SS C", "12 20 44 S 45 27 16 W");
194  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD SS MM C", "12 44 20 S 45 16 27 W");
195  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "MM DD SS C", "20 12 44 S 27 45 16 W");
196  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "MM SS DD C", "20 44 12 S 27 16 45 W");
197  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "SS DD MM C", "44 12 20 S 16 45 27 W");
198  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "SS MM DD C", "44 20 12 S 16 27 45 W");
199 }
200 
201 /*
202  * Test with and without the optional parameters.
203  */
204 static void
206 {
207  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD.DDD", "-12.346 -45.455");
208  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD.DDD C", "12.346 S 45.455 W");
210  "POINT(-45.4545 -12.34567)", "DD.DDD MM.MMM", "-12.000 20.740 -45.000 27.270");
212  "POINT(-45.4545 -12.34567)", "DD.DDD MM.MMM C", "12.000 20.740 S 45.000 27.270 W");
214  "POINT(-45.4545 -12.34567)", "DD.DDD MM.MMM SS.SSS", "-12.000 20.000 44.412 -45.000 27.000 16.200");
216  "POINT(-45.4545 -12.34567)", "DD.DDD MM.MMM SS.SSS C", "12.000 20.000 44.412 S 45.000 27.000 16.200 W");
217 }
218 
219 static void
221 {
223  "POINT(-45.4545 -12.34567)", "DD.DDDMM.MMMSS.SSSC", "12.00020.00044.412S 45.00027.00016.200W");
224  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DDMM.MMM", "-1220.740 -4527.270");
225  /* "##." will be printed as "##" */
226  test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD.MM.MMM", "-1220.740 -4527.270");
227 }
228 
229 /*
230  * Test using formats that should produce errors.
231  */
232 static void
234 {
235  test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "DD.DDD SS.SSS");
236  test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "MM.MMM SS.SSS");
237  test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "DD.DDD SS.SSS DD");
238  test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "DD MM SS MM");
239  test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "DD MM SS SS");
240  test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "C DD.DDD C");
241  test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)",
242  "C \xC2"
243  "DD.DDD");
244  test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "C DD.DDD \xC2");
245  test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)",
246  "C DD\x80"
247  "MM ");
248  test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)",
249  "C DD \xFF"
250  "MM");
251  test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)",
252  "C DD \xB0"
253  "MM");
255  "POINT(1.23456 7.89012)",
256  "DD.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
258  "POINT(1.23456 7.89012)",
259  "DD.DDD jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
260 }
261 
263 
264 #define assert_lwprint_equal(d, precision, expected) \
265  lwprint_double((d), (precision), result); \
266  ASSERT_STRING_EQUAL(result, (expected));
267 
268 static void
270 {
271  static const int precision_start = -1; /* Check for negatives */
272  static const int precision_end = OUT_MAX_DIGITS + 2; /* Ask for more digits than available in all cases */
273 
274  /* Negative zero should be printed as 0 */
275  for (int i = precision_start; i < precision_end; i++)
276  assert_lwprint_equal(-0, i, "0");
277 
278  /* 2 = 0x4000000000000000
279  * -2 = 0xC000000000000000
280  * Both with exact representation, so we should never see extra digits
281  */
282  for (int i = precision_start; i < precision_end; i++)
283  {
284  assert_lwprint_equal(2.0, i, "2");
285  assert_lwprint_equal(-2.0, i, "-2");
286  }
287 
288  /* 0.3 doesn't have an exact representation but it's the shortest representation for 0x3FD3333333333333
289  * 2.99999999999999988897769753748E-1 = 0x3FD3333333333333
290  */
291  assert_lwprint_equal(0.3, 0, "0");
292  for (int i = 1; i < precision_end; i++)
293  {
294  assert_lwprint_equal(0.3, i, "0.3");
295  assert_lwprint_equal(2.99999999999999988897769753748E-1, i, "0.3");
296  }
297 
298  /* 2.5 has an exact representation (0x4004000000000000) */
299  assert_lwprint_equal(2.5, 0, "2");
300  for (int i = 1; i < precision_end; i++)
301  {
302  assert_lwprint_equal(2.5, i, "2.5");
303  }
304 
305  /* Test trailing zeros and rounding
306  * 0.0000000298023223876953125 == 0x3E60000000000000 == 2.98023223876953125E-8
307  */
308  assert_lwprint_equal(0.0000000298023223876953125, -1, "0");
309  assert_lwprint_equal(0.0000000298023223876953125, 0, "0");
310  assert_lwprint_equal(0.0000000298023223876953125, 1, "0");
311  assert_lwprint_equal(0.0000000298023223876953125, 2, "0");
312  assert_lwprint_equal(0.0000000298023223876953125, 3, "0");
313  assert_lwprint_equal(0.0000000298023223876953125, 4, "0");
314  assert_lwprint_equal(0.0000000298023223876953125, 5, "0");
315  assert_lwprint_equal(0.0000000298023223876953125, 6, "0");
316  assert_lwprint_equal(0.0000000298023223876953125, 7, "0");
317  assert_lwprint_equal(0.0000000298023223876953125, 8, "0.00000003");
318  assert_lwprint_equal(0.0000000298023223876953125, 9, "0.00000003");
319  assert_lwprint_equal(0.0000000298023223876953125, 10, "0.0000000298");
320  assert_lwprint_equal(0.0000000298023223876953125, 11, "0.0000000298");
321  assert_lwprint_equal(0.0000000298023223876953125, 12, "0.000000029802");
322  assert_lwprint_equal(0.0000000298023223876953125, 13, "0.0000000298023");
323  assert_lwprint_equal(0.0000000298023223876953125, 14, "0.00000002980232");
324  assert_lwprint_equal(0.0000000298023223876953125, 15, "0.000000029802322");
325  assert_lwprint_equal(0.0000000298023223876953125, 16, "0.0000000298023224");
326  assert_lwprint_equal(0.0000000298023223876953125, 17, "0.00000002980232239");
327  assert_lwprint_equal(0.0000000298023223876953125, 18, "0.000000029802322388");
328  assert_lwprint_equal(0.0000000298023223876953125, 19, "0.0000000298023223877");
329  assert_lwprint_equal(0.0000000298023223876953125, 20, "0.0000000298023223877");
330  assert_lwprint_equal(0.0000000298023223876953125, 21, "0.000000029802322387695");
331  assert_lwprint_equal(0.0000000298023223876953125, 22, "0.0000000298023223876953");
332  assert_lwprint_equal(0.0000000298023223876953125, 23, "0.00000002980232238769531");
333  assert_lwprint_equal(0.0000000298023223876953125, 24, "0.000000029802322387695312");
334  assert_lwprint_equal(0.0000000298023223876953125, 40, "0.000000029802322387695312");
335 
336  /* Negative 0 after rounding should be printed as 0 */
337  assert_lwprint_equal(-0.0005, 0, "0");
338  assert_lwprint_equal(-0.0005, 1, "0");
339  assert_lwprint_equal(-0.0005, 2, "0");
340  assert_lwprint_equal(-0.0005, 3, "0");
341  assert_lwprint_equal(-0.0005, 4, "-0.0005");
342 
343  /* Rounding on the first decimal digit */
344  assert_lwprint_equal(-2.5, 0, "-2");
345  assert_lwprint_equal(-1.5, 0, "-2");
346  assert_lwprint_equal(-0.99, 0, "-1");
347  assert_lwprint_equal(-0.5, 0, "0");
348  assert_lwprint_equal(-0.01, 0, "0");
349  assert_lwprint_equal(0.5, 0, "0");
350  assert_lwprint_equal(0.99, 0, "1");
351  assert_lwprint_equal(1.5, 0, "2");
352  assert_lwprint_equal(2.5, 0, "2");
353 
354  /* Check rounding */
355  assert_lwprint_equal(0.035, 2, "0.04");
356  assert_lwprint_equal(0.045, 2, "0.04");
357  assert_lwprint_equal(0.04500000000000001, 2, "0.05");
358  assert_lwprint_equal(0.077, 2, "0.08");
359  assert_lwprint_equal(0.087, 2, "0.09");
360  assert_lwprint_equal(1.05, 1, "1");
361  assert_lwprint_equal(1.005, 2, "1");
362  assert_lwprint_equal(2.05, 1, "2");
363  assert_lwprint_equal(2.005, 2, "2");
364 
365  for (int i = 0; i < 15; i++)
366  assert_lwprint_equal(-0.99999999999999988898, i, "-1");
367  for (int i = 15; i < 20; i++)
368  assert_lwprint_equal(-0.99999999999999988898, i, "-0.9999999999999999");
369 
370  for (int i = 0; i < 16; i++)
371  assert_lwprint_equal(0.99999999999999977796, i, "1");
372  for (int i = 16; i < 20; i++)
373  assert_lwprint_equal(0.99999999999999977796, i, "0.9999999999999998");
374 
375  assert_lwprint_equal(0.0999999999999999916733273153113, 0, "0");
376  assert_lwprint_equal(-0.0999999999999999916733273153113, 0, "0");
377  for (int i = 1; i < 15; i++)
378  {
379  assert_lwprint_equal(0.0999999999999999916733273153113, i, "0.1");
380  assert_lwprint_equal(-0.0999999999999999916733273153113, i, "-0.1");
381  }
382 
383  assert_lwprint_equal(0.00999999999999999847, 0, "0");
384  assert_lwprint_equal(-0.00999999999999999847, 0, "0");
385  assert_lwprint_equal(0.00999999999999999847, 1, "0");
386  assert_lwprint_equal(-0.00999999999999999847, 1, "0");
387  for (int i = 2; i < 15; i++)
388  {
389  assert_lwprint_equal(0.00999999999999999847, i, "0.01");
390  assert_lwprint_equal(-0.00999999999999999847, i, "-0.01");
391  }
392 
393  /* Test regression changes (output that changed in the tests vs 3.0) */
394  /* There is at most 17 significative digits */
395  assert_lwprint_equal(-123456789012345.12345678, 20, "-123456789012345.12");
396  assert_lwprint_equal(123456789012345.12345678, 20, "123456789012345.12");
397 
398  /* Precision is respected (as number of decimal digits) */
399  assert_lwprint_equal(92115.51207431706, 12, "92115.51207431706");
400  assert_lwprint_equal(463412.82600000006, 12, "463412.82600000006");
401  assert_lwprint_equal(463462.2069374289, 12, "463462.2069374289");
402  assert_lwprint_equal(-115.17281600000001, OUT_DEFAULT_DECIMAL_DIGITS, "-115.17281600000001");
403  assert_lwprint_equal(-115.17281600000001, 12, "-115.172816");
404  assert_lwprint_equal(36.11464599999999, OUT_DEFAULT_DECIMAL_DIGITS, "36.11464599999999");
405  assert_lwprint_equal(36.11464599999999, 12, "36.114646");
406  assert_lwprint_equal(400000, 0, "400000");
407  assert_lwprint_equal(400000, 12, "400000");
408  assert_lwprint_equal(400000, 20, "400000");
409  assert_lwprint_equal(5.0833333333333330372738600999582558870316, 15, "5.083333333333333");
410  assert_lwprint_equal(1.4142135623730951, 15, "1.414213562373095");
411  assert_lwprint_equal(143.62025166838282, 15, "143.62025166838282");
412  assert_lwprint_equal(-30.037497356076827, 15, "-30.037497356076827");
413  assert_lwprint_equal(142.92857147299705, 15, "142.92857147299705");
414  assert_lwprint_equal(-32.75101196874403, 15, "-32.75101196874403");
415 
416  /* Note about this:
417  * 149.57565307617187 == 0x4062B26BC0000000
418  * 149.57565307617188 == 0x4062B26BC0000000
419  *
420  * 0x4062B26BC0000000 == 149.575653076171875
421  * Both if we consider "round to nearest, ties to even" (which is what we use)
422  * or "round to nearest, ties away from zero":
423  * 75 => 80 => 8 for the last digit
424  *
425  * It acts the same way in PostgreSQL:
426  # Select '149.57565307617187'::float8, '149.575653076171875'::float8, '149.57565307617188'::float8;
427  float8 | float8 | float8
428  --------------------+--------------------+--------------------
429  149.57565307617188 | 149.57565307617188 | 149.57565307617188
430  (1 row)
431  */
432  assert_lwprint_equal(149.57565307617187, 15, "149.57565307617188");
433  assert_lwprint_equal(-149.57565307617187, 15, "-149.57565307617188");
434 
435  /* Shortest representation is used */
436  assert_lwprint_equal(7000109.9999999990686774253845214843750000000000, 8, "7000110");
437  assert_lwprint_equal(7000109.9999999990686774253845214843750000000000, 12, "7000109.999999999");
438 
439  /* SnapToGrid by itself is not enough to limit output decimals */
440  const double d = 526355.92112222222;
441  const double gridsize = 0.00001;
442  const double gridded = rint(d / gridsize) * gridsize; /* Formula from ptarray_grid_in_place */
443  assert_lwprint_equal(gridded, 15, "526355.9211200001");
444  assert_lwprint_equal(gridded, 5, "526355.92112");
445 
446  /* Test the change towards scientific notation */
447  assert_lwprint_equal(nextafter(OUT_MAX_DOUBLE, 0), OUT_MAX_DIGITS, "999999999999999.9");
448  assert_lwprint_equal(nextafter(-OUT_MAX_DOUBLE, 0), OUT_MAX_DIGITS, "-999999999999999.9");
451  assert_lwprint_equal(nextafter(OUT_MAX_DOUBLE, INFINITY), OUT_MAX_DIGITS, "1.0000000000000001e+15");
452  assert_lwprint_equal(nextafter(-OUT_MAX_DOUBLE, -INFINITY), OUT_MAX_DIGITS, "-1.0000000000000001e+15");
453 
454  assert_lwprint_equal(nextafter(OUT_MIN_DOUBLE, 0), OUT_MAX_DIGITS, "9.999999999999999e-9");
455  assert_lwprint_equal(nextafter(-OUT_MIN_DOUBLE, 0), OUT_MAX_DIGITS, "-9.999999999999999e-9");
458  assert_lwprint_equal(nextafter(OUT_MIN_DOUBLE, INFINITY), OUT_MAX_DIGITS, "0.000000010000000000000002");
459  assert_lwprint_equal(nextafter(-OUT_MIN_DOUBLE, -INFINITY), OUT_MAX_DIGITS, "-0.000000010000000000000002");
460 
461 
462  /* Big numbers that use scientific notation respect the precision parameter */
463  assert_lwprint_equal(9e+300, 0, "9e+300");
464  assert_lwprint_equal(9e+300, 15, "9e+300");
465  assert_lwprint_equal(-9e+300, 0, "-9e+300");
466  assert_lwprint_equal(-9e+300, 15, "-9e+300");
467  assert_lwprint_equal(9.000000000000001e+300, 0, "9e+300");
468  assert_lwprint_equal(9.000000000000001e+300, 15, "9.000000000000001e+300");
469  assert_lwprint_equal(-9.000000000000001e+300, 0, "-9e+300");
470  assert_lwprint_equal(-9.000000000000001e+300, 15, "-9.000000000000001e+300");
471 
472  assert_lwprint_equal(6917529027641081856.0, 17, "6.917529027641082e+18");
473  assert_lwprint_equal(6917529027641081856.0, 16, "6.917529027641082e+18");
474  assert_lwprint_equal(6917529027641081856.0, 15, "6.917529027641082e+18");
475  assert_lwprint_equal(6917529027641081856.0, 14, "6.91752902764108e+18");
476  assert_lwprint_equal(6917529027641081856.0, 13, "6.9175290276411e+18");
477  assert_lwprint_equal(6917529027641081856.0, 12, "6.917529027641e+18");
478  assert_lwprint_equal(6917529027641081856.0, 11, "6.91752902764e+18");
479  assert_lwprint_equal(6917529027641081856.0, 10, "6.9175290276e+18");
480  assert_lwprint_equal(6917529027641081856.0, 9, "6.917529028e+18");
481  assert_lwprint_equal(6917529027641081856.0, 8, "6.91752903e+18");
482  assert_lwprint_equal(6917529027641081856.0, 7, "6.917529e+18");
483  assert_lwprint_equal(6917529027641081856.0, 6, "6.917529e+18");
484  assert_lwprint_equal(6917529027641081856.0, 5, "6.91753e+18");
485  assert_lwprint_equal(6917529027641081856.0, 4, "6.9175e+18");
486  assert_lwprint_equal(6917529027641081856.0, 3, "6.918e+18");
487  assert_lwprint_equal(6917529027641081856.0, 2, "6.92e+18");
488  assert_lwprint_equal(6917529027641081856.0, 1, "6.9e+18");
489  assert_lwprint_equal(6917529027641081856.0, 0, "7e+18");
490 
491  /* Test special values (+-inf, NaNs) */
492  for (int i = precision_start; i < precision_end; i++)
493  {
494  assert_lwprint_equal(NAN, i, "NaN");
495  assert_lwprint_equal(INFINITY, i, "Infinity");
496  assert_lwprint_equal(-INFINITY, i, "-Infinity");
497  }
498 
499  /* Extremes */
500  assert_lwprint_equal(2.2250738585072014e-308, OUT_MAX_DIGITS, "2.2250738585072014e-308");
501  assert_lwprint_equal(1.7976931348623157e+308, OUT_MAX_DIGITS, "1.7976931348623157e+308"); /* Max */
502  assert_lwprint_equal(2.9802322387695312E-8, OUT_MAX_DIGITS, "0.000000029802322387695312"); /* Trailing zeros */
503 }
504 
505 /* Macro to test rountrip of lwprint_double when using enough precision digits (OUT_MAX_DIGITS) */
506 #define assert_lwprint_roundtrip(d) \
507  { \
508  char s[OUT_DOUBLE_BUFFER_SIZE] = {0}; \
509  lwprint_double(d, OUT_MAX_DIGITS, s); \
510  ASSERT_DOUBLE_EQUAL(atof(s), d); \
511  }
512 
513 static void
515 {
516  /* Test roundtrip with the first value outside the range that's always printed as zero */
517  assert_lwprint_roundtrip(nextafter(FP_TOLERANCE, 1));
518  assert_lwprint_roundtrip(nextafter(-FP_TOLERANCE, -1));
519 
520  /* Test roundtrip in around the switch to scientific notation */
525  assert_lwprint_roundtrip(nextafter(OUT_MAX_DOUBLE, INFINITY));
526  assert_lwprint_roundtrip(nextafter(-OUT_MAX_DOUBLE, -INFINITY));
527 
528  /* Test some numbers */
530  assert_lwprint_roundtrip(0.0000000298023223876953125);
533  assert_lwprint_roundtrip(7000109.9999999990686774253845214843750000000000);
534  assert_lwprint_roundtrip(6917529027641081856.0);
535  assert_lwprint_roundtrip(9e+300);
536  assert_lwprint_roundtrip(-9e+300);
537  assert_lwprint_roundtrip(9.000000000000001e+300);
538  assert_lwprint_roundtrip(-9.000000000000001e+300);
539 
540  /* Even if we write the **same** number differently as the (compiler) input the roundtrip is guaranteed */
541  assert_lwprint_roundtrip(149.57565307617187);
542  assert_lwprint_roundtrip(149.57565307617188);
543  assert_lwprint_roundtrip(-149.57565307617187);
544  assert_lwprint_roundtrip(-149.57565307617188);
545 
546  /* Extremes */
547  assert_lwprint_roundtrip(2.2250738585072014e-308); /* We normalize small numbers to 0 */
548  assert_lwprint_roundtrip(1.7976931348623157e+308);
549  assert_lwprint_roundtrip(2.9802322387695312E-8);
550 
551  /* Special cases */
552  assert_lwprint_roundtrip(-0); /* -0 is considered equal to 0 */
553 
554  /* Disabled because Windows / MinGW doesn't like them (#4735)
555  * assert_lwprint_roundtrip(INFINITY);
556  * assert_lwprint_roundtrip(-INFINITY);
557  */
558 
559  /* nan is never equal to nan
560  * assert_lwprint_roundtrip(NAN);
561  */
562 }
563 
564 /*
565 ** Callback used by the test harness to register the tests in this file.
566 */
567 void print_suite_setup(void);
569 {
570  CU_pSuite suite = CU_add_suite("printing", NULL, NULL);
576  PG_ADD_TEST(suite, test_lwprint);
578 }
579 
static void test_lwpoint_to_latlon_default_format(void)
Definition: cu_print.c:66
#define assert_lwprint_roundtrip(d)
Definition: cu_print.c:506
static void test_lwpoint_to_latlon_oddball_formats(void)
Definition: cu_print.c:220
static void test_lwpoint_to_latlon_bad_formats(void)
Definition: cu_print.c:233
static void test_lwpoint_to_latlon_format_orders(void)
Definition: cu_print.c:170
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition: cu_print.c:262
#define assert_lwprint_equal(d, precision, expected)
Definition: cu_print.c:264
void print_suite_setup(void)
Definition: cu_print.c:568
static void test_lwprint_roundtrip(void)
Definition: cu_print.c:514
static void test_lwprint(void)
Definition: cu_print.c:269
static void test_lwpoint_to_latlon_optional_format(void)
Definition: cu_print.c:205
static void test_lwpoint_to_latlon_assert_error(char *point_wkt, const char *format)
Definition: cu_print.c:44
static void test_lwpoint_to_latlon_assert_format(char *point_wkt, const char *format, const char *expected)
Definition: cu_print.c:21
void cu_error_msg_reset()
char cu_error_msg[MAX_CUNIT_ERROR_LENGTH+1]
#define PG_ADD_TEST(suite, testfunc)
void lwpoint_free(LWPOINT *pt)
Definition: lwpoint.c:213
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:2085
void lwfree(void *mem)
Definition: lwutil.c:242
char * lwpoint_to_latlon(const LWPOINT *p, const char *format)
Definition: lwprint.c:431
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition: lwin_wkt.c:905
#define OUT_MAX_DIGITS
#define OUT_DEFAULT_DECIMAL_DIGITS
#define OUT_MAX_DOUBLE
#define OUT_MIN_DOUBLE
#define OUT_DOUBLE_BUFFER_SIZE
#define FP_TOLERANCE
Floating point comparators.
#define NAN
Definition: lwgeodetic.h:37