Fix more cases of loss of precision for large magnitude integers

This commit is contained in:
Eric Fischer 2017-11-09 13:40:31 -08:00
parent aa7191b1ee
commit fda0e1f28a
3 changed files with 18 additions and 13 deletions

21
mvt.cpp
View File

@ -6,6 +6,7 @@
#include <zlib.h>
#include <errno.h>
#include <limits.h>
#include <ctype.h>
#include "mvt.hpp"
#include "geometry.hpp"
#include "protozero/varint.hpp"
@ -420,7 +421,7 @@ std::string mvt_value::toString() {
if (type == mvt_string) {
return quote(string_value);
} else if (type == mvt_int) {
return std::to_string((long long) numeric_value.int_value);
return std::to_string(numeric_value.int_value);
} else if (type == mvt_double) {
double v = numeric_value.double_value;
if (v == (long long) v) {
@ -436,9 +437,9 @@ std::string mvt_value::toString() {
return milo::dtoa_milo(v);
}
} else if (type == mvt_sint) {
return std::to_string((long long) numeric_value.sint_value);
return std::to_string(numeric_value.sint_value);
} else if (type == mvt_uint) {
return std::to_string((long long) numeric_value.uint_value);
return std::to_string(numeric_value.uint_value);
} else if (type == mvt_bool) {
return numeric_value.bool_value ? "true" : "false";
} else {
@ -548,14 +549,18 @@ mvt_value stringified_to_mvt_value(int type, const char *s) {
if (type == mvt_double) {
long long v;
if (is_integer(s, &v)) {
if (v >= 0) {
unsigned long long uv;
if (is_unsigned_integer(s, &uv)) {
if (uv <= LLONG_MAX) {
tv.type = mvt_int;
tv.numeric_value.int_value = v;
tv.numeric_value.int_value = uv;
} else {
tv.type = mvt_sint;
tv.numeric_value.sint_value = v;
tv.type = mvt_uint;
tv.numeric_value.uint_value = uv;
}
} else if (is_integer(s, &v)) {
tv.type = mvt_sint;
tv.numeric_value.sint_value = v;
} else {
errno = 0;
char *endptr;

View File

@ -30,11 +30,11 @@
,
{ "type": "Feature", "properties": { "excess": -18446744073709553000 }, "geometry": { "type": "Point", "coordinates": [ 0.000000, 0.000000 ] } }
,
{ "type": "Feature", "properties": { "excess": 18446744073709553000 }, "geometry": { "type": "Point", "coordinates": [ 0.000000, 0.000000 ] } }
{ "type": "Feature", "properties": { "excess": 18446744073709551615 }, "geometry": { "type": "Point", "coordinates": [ 0.000000, 0.000000 ] } }
,
{ "type": "Feature", "properties": { "excess": -18446744073709553000 }, "geometry": { "type": "Point", "coordinates": [ 0.000000, 0.000000 ] } }
,
{ "type": "Feature", "properties": { "excess": 9223372036854776000 }, "geometry": { "type": "Point", "coordinates": [ 0.000000, 0.000000 ] } }
{ "type": "Feature", "properties": { "excess": 9223372036854775808 }, "geometry": { "type": "Point", "coordinates": [ 0.000000, 0.000000 ] } }
,
{ "type": "Feature", "properties": { "excess": -9223372036854775808 }, "geometry": { "type": "Point", "coordinates": [ 0.000000, 0.000000 ] } }
,

View File

@ -114,7 +114,7 @@ void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x,
fprintq(fp, val.string_value.c_str());
} else if (val.type == mvt_int) {
fprintq(fp, key);
fprintf(fp, ": %lld", (long long) val.numeric_value.int_value);
fprintf(fp, ": %lld", val.numeric_value.int_value);
} else if (val.type == mvt_double) {
fprintq(fp, key);
double v = val.numeric_value.double_value;
@ -133,10 +133,10 @@ void layer_to_geojson(FILE *fp, mvt_layer const &layer, unsigned z, unsigned x,
}
} else if (val.type == mvt_sint) {
fprintq(fp, key);
fprintf(fp, ": %lld", (long long) val.numeric_value.sint_value);
fprintf(fp, ": %lld", val.numeric_value.sint_value);
} else if (val.type == mvt_uint) {
fprintq(fp, key);
fprintf(fp, ": %lld", (long long) val.numeric_value.uint_value);
fprintf(fp, ": %llu", val.numeric_value.uint_value);
} else if (val.type == mvt_bool) {
fprintq(fp, key);
fprintf(fp, ": %s", val.numeric_value.bool_value ? "true" : "false");