PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
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
20static void
21test_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 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}
43static void
44test_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*/
65static 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");
99 NULL,
100 "90\xC2\xB0"
101 "0'0.000\"S 180\xC2\xB0"
102 "0'0.000\"E");
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");
119 NULL,
120 "90\xC2\xB0"
121 "0'0.000\"N 180\xC2\xB0"
122 "0'0.000\"W");
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 */
169static 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 */
204static void
206{
207 test_lwpoint_to_latlon_assert_format("POINT(21.9999999 1)",
208 "D-M-S-C", "1-0-0-N 22-0-0-E");
209 test_lwpoint_to_latlon_assert_format("POINT(21.99999999999 1)",
210 "D-M-S-C", "1-0-0-N 22-0-0-E");
211
212 test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD.DDD", "-12.346 -45.455");
213 test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD.DDD C", "12.346 S 45.455 W");
215 "POINT(-45.4545 -12.34567)", "DD.DDD MM.MMM", "-12.000 20.740 -45.000 27.270");
217 "POINT(-45.4545 -12.34567)", "DD.DDD MM.MMM C", "12.000 20.740 S 45.000 27.270 W");
219 "POINT(-45.4545 -12.34567)", "DD.DDD MM.MMM SS.SSS", "-12.000 20.000 44.412 -45.000 27.000 16.200");
221 "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");
222}
223
224static void
226{
228 "POINT(-45.4545 -12.34567)", "DD.DDDMM.MMMSS.SSSC", "12.00020.00044.412S 45.00027.00016.200W");
229 test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DDMM.MMM", "-1220.740 -4527.270");
230 /* "##." will be printed as "##" */
231 test_lwpoint_to_latlon_assert_format("POINT(-45.4545 -12.34567)", "DD.MM.MMM", "-1220.740 -4527.270");
232}
233
234/*
235 * Test using formats that should produce errors.
236 */
237static void
239{
240 test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "DD.DDD SS.SSS");
241 test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "MM.MMM SS.SSS");
242 test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "DD.DDD SS.SSS DD");
243 test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "DD MM SS MM");
244 test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "DD MM SS SS");
245 test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "C DD.DDD C");
246 test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)",
247 "C \xC2"
248 "DD.DDD");
249 test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)", "C DD.DDD \xC2");
250 test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)",
251 "C DD\x80"
252 "MM ");
253 test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)",
254 "C DD \xFF"
255 "MM");
256 test_lwpoint_to_latlon_assert_error("POINT(1.23456 7.89012)",
257 "C DD \xB0"
258 "MM");
260 "POINT(1.23456 7.89012)",
261 "DD.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
263 "POINT(1.23456 7.89012)",
264 "DD.DDD jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
265}
266
268
269#define assert_lwprint_equal(d, precision, expected) \
270 lwprint_double((d), (precision), result); \
271 ASSERT_STRING_EQUAL(result, (expected));
272
273static void
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}
509
510/* Macro to test roundtrip of lwprint_double when using enough precision digits (OUT_MAX_DIGITS) */
511#define assert_lwprint_roundtrip(d) \
512 { \
513 char s[OUT_DOUBLE_BUFFER_SIZE] = {0}; \
514 lwprint_double(d, OUT_MAX_DIGITS, s); \
515 ASSERT_DOUBLE_EQUAL(atof(s), d); \
516 }
517
518static void
520{
521 /* Test roundtrip with the first value outside the range that's always printed as zero */
523 assert_lwprint_roundtrip(nextafter(-FP_TOLERANCE, -1));
524
525 /* Test roundtrip in around the switch to scientific notation */
530 assert_lwprint_roundtrip(nextafter(OUT_MAX_DOUBLE, INFINITY));
531 assert_lwprint_roundtrip(nextafter(-OUT_MAX_DOUBLE, -INFINITY));
532
533 /* Test some numbers */
535 assert_lwprint_roundtrip(0.0000000298023223876953125);
538 assert_lwprint_roundtrip(7000109.9999999990686774253845214843750000000000);
539 assert_lwprint_roundtrip(6917529027641081856.0);
542 assert_lwprint_roundtrip(9.000000000000001e+300);
543 assert_lwprint_roundtrip(-9.000000000000001e+300);
544
545 /* Even if we write the **same** number differently as the (compiler) input the roundtrip is guaranteed */
546 assert_lwprint_roundtrip(149.57565307617187);
547 assert_lwprint_roundtrip(149.57565307617188);
548 assert_lwprint_roundtrip(-149.57565307617187);
549 assert_lwprint_roundtrip(-149.57565307617188);
550
551 /* Extremes */
552 assert_lwprint_roundtrip(2.2250738585072014e-308); /* We normalize small numbers to 0 */
553 assert_lwprint_roundtrip(1.7976931348623157e+308);
554 assert_lwprint_roundtrip(2.9802322387695312E-8);
555
556 /* Special cases */
557 assert_lwprint_roundtrip(-0); /* -0 is considered equal to 0 */
558
559 /* Disabled because Windows / MinGW doesn't like them (#4735)
560 * assert_lwprint_roundtrip(INFINITY);
561 * assert_lwprint_roundtrip(-INFINITY);
562 */
563
564 /* nan is never equal to nan
565 * assert_lwprint_roundtrip(NAN);
566 */
567}
568
569/*
570** Callback used by the test harness to register the tests in this file.
571*/
572void print_suite_setup(void);
584
static void test_lwpoint_to_latlon_default_format(void)
Definition cu_print.c:66
#define assert_lwprint_roundtrip(d)
Definition cu_print.c:511
static void test_lwpoint_to_latlon_oddball_formats(void)
Definition cu_print.c:225
static void test_lwpoint_to_latlon_bad_formats(void)
Definition cu_print.c:238
static void test_lwpoint_to_latlon_format_orders(void)
Definition cu_print.c:170
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition cu_print.c:267
#define assert_lwprint_equal(d, precision, expected)
Definition cu_print.c:269
void print_suite_setup(void)
Definition cu_print.c:573
static void test_lwprint_roundtrip(void)
Definition cu_print.c:519
static void test_lwprint(void)
Definition cu_print.c:274
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)
#define ASSERT_STRING_EQUAL(o, e)
char * lwpoint_to_latlon(const LWPOINT *p, const char *format)
Definition lwprint.c:437
void lwpoint_free(LWPOINT *pt)
Definition lwpoint.c:213
#define LW_PARSER_CHECK_NONE
Definition liblwgeom.h:2149
void lwfree(void *mem)
Definition lwutil.c:248
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
Definition lwin_wkt.c:940
#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