diff --git a/src/grib_accessor_class_data_ccsds_packing.cc b/src/grib_accessor_class_data_ccsds_packing.cc index 07f42539a..c41565bc8 100644 --- a/src/grib_accessor_class_data_ccsds_packing.cc +++ b/src/grib_accessor_class_data_ccsds_packing.cc @@ -329,6 +329,7 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len) f = (grib_power(bits_per_value, 2) - 1); minrange = grib_power(-last, 2) * f; maxrange = grib_power(last, 2) * f; + decimal_scale_factor = 0; while (range < minrange) { decimal_scale_factor += 1; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f7ee9e572..c597f0bc0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -281,6 +281,7 @@ if( HAVE_BUILD_TOOLS ) if( HAVE_AEC AND ENABLE_EXTRA_TESTS ) list(APPEND tests_extra grib_ecc-1431) + list(APPEND tests_extra grib_ecc-1433) endif() if( HAVE_FORTRAN AND ENABLE_EXTRA_TESTS ) list(APPEND tests_extra bufr_dump_encode_fortran) diff --git a/tests/grib_ecc-1431.cc b/tests/grib_ecc-1431.cc index ea799f2a3..2adb39fc5 100644 --- a/tests/grib_ecc-1431.cc +++ b/tests/grib_ecc-1431.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +32,7 @@ struct Range // // Test: This test doesn't accept errors after decompression. // -void test_full() +int main(int argc, char** argv) { std::vector ranges; ranges.push_back({ flt::max() / 10, flt::max() }); @@ -41,19 +42,15 @@ void test_full() ranges.push_back({ 1e-1, 1e-0 }); ranges.push_back({ 1e-2, 1e-1 }); ranges.push_back({ 1e-11, 1e-10 }); - // TODO - // The test fails for the following ranges - // These tests can be performed when the problem is solved with small values. - // ranges.push_back({flt::min()*10 , flt::min()*100 } ); - // ranges.push_back({flt::min() , flt::min()*10 } ); - // ranges.push_back({flt::min() , flt::max() } ); + ranges.push_back({ flt::min() * 10, flt::min() * 100 }); + ranges.push_back({ flt::min(), flt::min() * 10 }); + ranges.push_back({ flt::min(), flt::max() }); std::vector values_lens = { 1, 10, 100, 100000, - 10000000, }; int err; @@ -67,8 +64,12 @@ void test_full() for (const size_t in_values_len : values_lens) { for (const Range range : ranges) { Assert(range.min < range.max); - std::cout << "Testing: " << in_values_len << " " << range.min << " " << range.max << std::endl; - std::uniform_real_distribution unif(range.min, range.max); + std::cout << "Testing: " + << "n_vals : " << std::setw(7) << in_values_len + << " range(" << std::scientific << std::setw(12) << range.min << ", " << std::setw(12) << range.max << ") " + << std::endl; + std::uniform_real_distribution + unif(range.min, range.max); codes_handle* handle = codes_grib_handle_new_from_samples(0, "reduced_gg_pl_128_grib2"); double* in_values = new double[in_values_len]; @@ -116,96 +117,5 @@ void test_full() delete[] grid_ccsds_values; } } -} - - -// -// Test: This test accepts tolerates errors. Values after decompression must be within a certain user defined range. -// -void test_simplified() -{ - std::vector ranges; - ranges.push_back({ flt::max() / 10, flt::max() }); - ranges.push_back({ flt::max() / 100, flt::max() / 10 }); - ranges.push_back({ 1e+9, 1e+10 }); - ranges.push_back({ 1e+0, 1e+1 }); - ranges.push_back({ 1e-1, 1e-0 }); - ranges.push_back({ 1e-2, 1e-1 }); - ranges.push_back({ 1e-11, 1e-10 }); - // TODO - // The test fails for the following ranges - // These tests can be performed when the problem is solved with small values. - // ranges.push_back({flt::min()*10 , flt::min()*100 } ); - // ranges.push_back({flt::min() , flt::min()*10 } ); - // ranges.push_back({flt::min() , flt::max() } ); - - std::vector values_lens = { - 1, - 10, - 100, - 100000, - 10000000, - }; - - int err; - - std::default_random_engine re; - size_t grid_ccsds_values_len = 0; - std::string packing_type = ""; - size_t size = 0; - - for (const size_t in_values_len : values_lens) { - for (const Range range : ranges) { - Assert(range.min < range.max); - std::cout << "Testing: " << in_values_len << " " << range.min << " " << range.max << std::endl; - std::uniform_real_distribution unif(range.min, range.max); - - codes_handle* handle = codes_grib_handle_new_from_samples(0, "reduced_gg_pl_128_grib2"); - double* in_values = new double[in_values_len]; - double* grid_ccsds_values = new double[in_values_len]; - - grid_ccsds_values_len = in_values_len; - - // Initialize with random values - for (size_t i = 0; i < in_values_len; ++i) { - in_values[i] = unif(re); - } - - // Test grid_ccsds - packing_type = "grid_ccsds"; - size = packing_type.size(); - CODES_CHECK(codes_set_string(handle, "packingType", packing_type.c_str(), &size), 0); - if ((err = codes_set_double_array(handle, "values", in_values, in_values_len)) != 0) { - Assert(!"CCSDS encoding failed"); - } - if ((err = codes_get_double_array(handle, "values", grid_ccsds_values, &grid_ccsds_values_len)) != 0) { - Assert(!"CCSDS decoding failed"); - } - Assert(grid_ccsds_values_len == in_values_len); - - // Test buffers - double tolerance = 0.000001; - for (size_t i = 0; i < grid_ccsds_values_len; ++i) { - if (!((grid_ccsds_values[i] < (in_values[i] * (1 + tolerance))) && - grid_ccsds_values[i] > (in_values[i] / (1 + tolerance)))) { - std::cout.precision(dbl::max_digits10); - std::cout << "Test failed: " << grid_ccsds_values[i] << " != " << in_values[i] << std::endl; - Assert(0); - } - } - - codes_handle_delete(handle); - - delete[] in_values; - delete[] grid_ccsds_values; - } - } -} - - -int main(int argc, char** argv) -{ - test_simplified(); - //test_full(); return 0; } diff --git a/tests/grib_ecc-1433.cc b/tests/grib_ecc-1433.cc new file mode 100644 index 000000000..ed2ac04aa --- /dev/null +++ b/tests/grib_ecc-1433.cc @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2005- ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * + * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by + * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. + */ + +#include "grib_api_internal.h" +#include +#include +#include +#include +#include +#include +#include +#include + +typedef std::numeric_limits dbl; +typedef std::numeric_limits flt; + +int main(int argc, char** argv) +{ + size_t values_len = 10; + std::default_random_engine re; + std::uniform_real_distribution unif(flt::min(), flt::min() * 10); + + codes_handle* handle = codes_grib_handle_new_from_samples(0, "reduced_gg_pl_128_grib2"); + double* values = new double[values_len]; + double* grid_ccsds_values = new double[values_len]; + + // Initialize with small random values + for (size_t i = 0; i < values_len; ++i) { + values[i] = unif(re); + } + + // Test grid_ccsds + std::string packing_type = "grid_ccsds"; + size_t size = packing_type.size(); + CODES_CHECK(codes_set_double_array(handle, "values", values, values_len), 0); + CODES_CHECK(codes_set_string(handle, "packingType", packing_type.c_str(), &size), 0); + CODES_CHECK(codes_get_double_array(handle, "values", grid_ccsds_values, &values_len), 0); + + // Test buffers + double tolerance = 0.000001; + for (size_t i = 0; i < values_len; ++i) { + if (!((grid_ccsds_values[i] < (values[i] * (1 + tolerance))) && + grid_ccsds_values[i] > (values[i] / (1 + tolerance)))) { + std::cout.precision(dbl::max_digits10); + std::cout << "Test failed: " << grid_ccsds_values[i] << " != " << values[i] << std::endl; + Assert(0); + } + } + + codes_handle_delete(handle); + + delete[] values; + delete[] grid_ccsds_values; + return 0; +} diff --git a/tests/grib_ecc-1433.sh b/tests/grib_ecc-1433.sh new file mode 100755 index 000000000..9fd834346 --- /dev/null +++ b/tests/grib_ecc-1433.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# (C) Copyright 2005- ECMWF. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# +# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by +# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. +# + +. ./include.ctest.sh + +label="grib_ecc-1433_test" +temp=temp.$label + +$EXEC $test_dir/grib_ecc-1433 + +rm -f $temp