From 3e03508e043123dbdc3ebb00ce6c67f12c8f8c47 Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Wed, 11 Jul 2018 09:49:22 -0400 Subject: Fix #1074. Fix unit conversion factors for geod. Previously, unit conversion using atof(unit_list[i].to_meter) which gives the wrong answer with, e.g., "1/10". Now it directly uses unit_list[i].factor (e.g., 0.1). Also fix all the conversion factors for the US Surveyor units so that they are the closest doubles. E.g., the conversion factors for US feet are factor rel error old 0.304800609601219 6e-16 12/39.37 1e-16 now 1200/3937.0 5e-17 Maybe someone should check the Indian units (but it's possible that India and Pakistan have different standards). --- src/geod_set.c | 2 +- src/pj_units.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/geod_set.c b/src/geod_set.c index 479f18da..dacb0c73 100644 --- a/src/geod_set.c +++ b/src/geod_set.c @@ -37,7 +37,7 @@ geod_set(int argc, char **argv) { for (i = 0; (s = unit_list[i].id) && strcmp(name, s) ; ++i) ; if (!s) emess(1,"%s unknown unit conversion id", name); - fr_meter = 1. / (to_meter = atof(unit_list[i].to_meter)); + fr_meter = 1. / (to_meter = unit_list[i].factor); } else to_meter = fr_meter = 1.; geod_f = es/(1 + sqrt(1 - es)); diff --git a/src/pj_units.c b/src/pj_units.c index 59ff1ebe..e8421dea 100644 --- a/src/pj_units.c +++ b/src/pj_units.c @@ -12,12 +12,12 @@ ** numerator/denomenator values (e.g. 1/1000) */ C_NAMESPACE_VAR const struct PJ_UNITS pj_units[] = { - {"km", "1000.", "Kilometer", 1000.0}, - {"m", "1.", "Meter", 1.0}, + {"km", "1000", "Kilometer", 1000.0}, + {"m", "1", "Meter", 1.0}, {"dm", "1/10", "Decimeter", 0.1}, {"cm", "1/100", "Centimeter", 0.01}, {"mm", "1/1000", "Millimeter", 0.001}, - {"kmi", "1852.0", "International Nautical Mile", 1852.0}, + {"kmi", "1852", "International Nautical Mile", 1852.0}, {"in", "0.0254", "International Inch", 0.0254}, {"ft", "0.3048", "International Foot", 0.3048}, {"yd", "0.9144", "International Yard", 0.9144}, @@ -25,11 +25,11 @@ pj_units[] = { {"fath", "1.8288", "International Fathom", 1.8288}, {"ch", "20.1168", "International Chain", 20.1168}, {"link", "0.201168", "International Link", 0.201168}, - {"us-in", "1./39.37", "U.S. Surveyor's Inch", 0.0254}, - {"us-ft", "0.304800609601219", "U.S. Surveyor's Foot", 0.304800609601219}, - {"us-yd", "0.914401828803658", "U.S. Surveyor's Yard", 0.914401828803658}, - {"us-ch", "20.11684023368047", "U.S. Surveyor's Chain", 20.11684023368047}, - {"us-mi", "1609.347218694437", "U.S. Surveyor's Statute Mile", 1609.347218694437}, + {"us-in", "1/39.37", "U.S. Surveyor's Inch", 100/3937.0}, + {"us-ft", "12/39.37", "U.S. Surveyor's Foot", 1200/3937.0}, + {"us-yd", "36/39.37", "U.S. Surveyor's Yard", 3600/3937.0}, + {"us-ch", "792/39.37", "U.S. Surveyor's Chain", 79200/3937.0}, + {"us-mi", "63360/39.37", "U.S. Surveyor's Statute Mile", 6336000/3937.0}, {"ind-yd", "0.91439523", "Indian Yard", 0.91439523}, {"ind-ft", "0.30479841", "Indian Foot", 0.30479841}, {"ind-ch", "20.11669506", "Indian Chain", 20.11669506}, -- cgit v1.2.3 From a7f05deb5504d202dbb37654fad54cb42957251a Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Wed, 11 Jul 2018 10:01:26 -0400 Subject: Remove ugly assignment within an expression. --- src/geod_set.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/geod_set.c b/src/geod_set.c index dacb0c73..1116e7ee 100644 --- a/src/geod_set.c +++ b/src/geod_set.c @@ -37,7 +37,8 @@ geod_set(int argc, char **argv) { for (i = 0; (s = unit_list[i].id) && strcmp(name, s) ; ++i) ; if (!s) emess(1,"%s unknown unit conversion id", name); - fr_meter = 1. / (to_meter = unit_list[i].factor); + to_meter = unit_list[i].factor; + fr_meter = 1 / to_meter; } else to_meter = fr_meter = 1.; geod_f = es/(1 + sqrt(1 - es)); -- cgit v1.2.3 From 3efab3e9ee22de67651ee24c89ac750c212cc9a0 Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Wed, 11 Jul 2018 11:10:28 -0400 Subject: Revert pj_units to_meters entries for US units. Bletch, pj_init also decodes the to_meters field of pj_unit, but only handles plain numbers or 1/nnn, but not 1./nnn or mmm/nnn. (So the original code would have not decoded the us-in entry properly.) Probably pj_init should be changed to use the factor field instead. Alternatively pj_init should look for a "/" anywhere in the field and decode the numerator and denominator as separate doubles. This would be needed if ratios are ever to be entered directly by the user (this is the strategy used by GeographicLib). And then, of course, the functionality should be provided by a separate utility function. --- src/geod_set.c | 2 +- src/pj_units.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/geod_set.c b/src/geod_set.c index 1116e7ee..bd388d34 100644 --- a/src/geod_set.c +++ b/src/geod_set.c @@ -40,7 +40,7 @@ geod_set(int argc, char **argv) { to_meter = unit_list[i].factor; fr_meter = 1 / to_meter; } else - to_meter = fr_meter = 1.; + to_meter = fr_meter = 1; geod_f = es/(1 + sqrt(1 - es)); geod_ini(); /* check if line or arc mode */ diff --git a/src/pj_units.c b/src/pj_units.c index e8421dea..44abaf34 100644 --- a/src/pj_units.c +++ b/src/pj_units.c @@ -26,10 +26,10 @@ pj_units[] = { {"ch", "20.1168", "International Chain", 20.1168}, {"link", "0.201168", "International Link", 0.201168}, {"us-in", "1/39.37", "U.S. Surveyor's Inch", 100/3937.0}, - {"us-ft", "12/39.37", "U.S. Surveyor's Foot", 1200/3937.0}, - {"us-yd", "36/39.37", "U.S. Surveyor's Yard", 3600/3937.0}, - {"us-ch", "792/39.37", "U.S. Surveyor's Chain", 79200/3937.0}, - {"us-mi", "63360/39.37", "U.S. Surveyor's Statute Mile", 6336000/3937.0}, + {"us-ft", "0.304800609601219", "U.S. Surveyor's Foot", 1200/3937.0}, + {"us-yd", "0.914401828803658", "U.S. Surveyor's Yard", 3600/3937.0}, + {"us-ch", "20.11684023368047", "U.S. Surveyor's Chain", 79200/3937.0}, + {"us-mi", "1609.347218694437", "U.S. Surveyor's Statute Mile", 6336000/3937.0}, {"ind-yd", "0.91439523", "Indian Yard", 0.91439523}, {"ind-ft", "0.30479841", "Indian Foot", 0.30479841}, {"ind-ch", "20.11669506", "Indian Chain", 20.11669506}, -- cgit v1.2.3