mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Merge pull request #25351 from Kumataro:fix25073_format_g
core: persistence: output reals as human-friendly expression. #25351 Close #25073 Related https://github.com/opencv/opencv/pull/25087 This patch is need to merge same time with https://github.com/opencv/opencv_contrib/pull/3714 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
@@ -76,9 +76,11 @@ char* doubleToString( char* buf, size_t bufSize, double value, bool explicitZero
|
||||
}
|
||||
else
|
||||
{
|
||||
static const char* fmt = "%.16e";
|
||||
// binary64 has 52 bit fraction with hidden bit.
|
||||
// 53 * log_10(2) is 15.955. So "%.16f" should be fine, but its test fails.
|
||||
snprintf( buf, bufSize, "%.17g", value );
|
||||
|
||||
char* ptr = buf;
|
||||
snprintf( buf, bufSize, fmt, value );
|
||||
if( *ptr == '+' || *ptr == '-' )
|
||||
ptr++;
|
||||
for( ; cv_isdigit(*ptr); ptr++ )
|
||||
@@ -118,11 +120,21 @@ char* floatToString( char* buf, size_t bufSize, float value, bool halfprecision,
|
||||
}
|
||||
else
|
||||
{
|
||||
char* ptr = buf;
|
||||
if (halfprecision)
|
||||
snprintf(buf, bufSize, "%.4e", value);
|
||||
{
|
||||
// bfloat16 has 7 bit fraction with hidden bit.
|
||||
// binary16 has 10 bit fraction with hidden bit.
|
||||
// 11 * log_10(2) is 3.311. So "%.4f" should be fine, but its test fails.
|
||||
snprintf(buf, bufSize, "%.5g", value);
|
||||
}
|
||||
else
|
||||
snprintf(buf, bufSize, "%.8e", value);
|
||||
{
|
||||
// binray32 has 23 bit fraction with hidden bit.
|
||||
// 24 * log_10(2) is 7.225. So "%.8f" should be fine, but its test fails.
|
||||
snprintf(buf, bufSize, "%.9g", value);
|
||||
}
|
||||
|
||||
char* ptr = buf;
|
||||
if( *ptr == '+' || *ptr == '-' )
|
||||
ptr++;
|
||||
for( ; cv_isdigit(*ptr); ptr++ )
|
||||
|
||||
@@ -1189,11 +1189,7 @@ TEST(Core_InputOutput, FileStorage_DMatch)
|
||||
|
||||
EXPECT_NO_THROW(fs << "d" << d);
|
||||
cv::String fs_result = fs.releaseAndGetString();
|
||||
#if defined _MSC_VER && _MSC_VER <= 1800 /* MSVC 2013 and older */
|
||||
EXPECT_STREQ(fs_result.c_str(), "%YAML:1.0\n---\nd: [ 1, 2, 3, -1.5000000000000000e+000 ]\n");
|
||||
#else
|
||||
EXPECT_STREQ(fs_result.c_str(), "%YAML:1.0\n---\nd: [ 1, 2, 3, -1.5000000000000000e+00 ]\n");
|
||||
#endif
|
||||
EXPECT_STREQ(fs_result.c_str(), "%YAML:1.0\n---\nd: [ 1, 2, 3, -1.5 ]\n");
|
||||
|
||||
cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
|
||||
|
||||
@@ -1220,25 +1216,14 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector)
|
||||
|
||||
EXPECT_NO_THROW(fs << "dv" << dv);
|
||||
cv::String fs_result = fs.releaseAndGetString();
|
||||
#if defined _MSC_VER && _MSC_VER <= 1800 /* MSVC 2013 and older */
|
||||
EXPECT_STREQ(fs_result.c_str(),
|
||||
"%YAML:1.0\n"
|
||||
"---\n"
|
||||
"dv:\n"
|
||||
" - [ 1, 2, 3, -1.5000000000000000e+000 ]\n"
|
||||
" - [ 2, 3, 4, 1.5000000000000000e+000 ]\n"
|
||||
" - [ 3, 2, 1, 5.0000000000000000e-001 ]\n"
|
||||
" - [ 1, 2, 3, -1.5 ]\n"
|
||||
" - [ 2, 3, 4, 1.5 ]\n"
|
||||
" - [ 3, 2, 1, 0.5 ]\n"
|
||||
);
|
||||
#else
|
||||
EXPECT_STREQ(fs_result.c_str(),
|
||||
"%YAML:1.0\n"
|
||||
"---\n"
|
||||
"dv:\n"
|
||||
" - [ 1, 2, 3, -1.5000000000000000e+00 ]\n"
|
||||
" - [ 2, 3, 4, 1.5000000000000000e+00 ]\n"
|
||||
" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n"
|
||||
);
|
||||
#endif
|
||||
|
||||
cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
|
||||
|
||||
@@ -1278,33 +1263,18 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector_vector)
|
||||
EXPECT_NO_THROW(fs << "dvv" << dvv);
|
||||
cv::String fs_result = fs.releaseAndGetString();
|
||||
#ifndef OPENCV_TRAITS_ENABLE_DEPRECATED
|
||||
#if defined _MSC_VER && _MSC_VER <= 1800 /* MSVC 2013 and older */
|
||||
EXPECT_STREQ(fs_result.c_str(),
|
||||
"%YAML:1.0\n"
|
||||
"---\n"
|
||||
"dvv:\n"
|
||||
" -\n"
|
||||
" - [ 1, 2, 3, -1.5000000000000000e+000 ]\n"
|
||||
" - [ 2, 3, 4, 1.5000000000000000e+000 ]\n"
|
||||
" - [ 3, 2, 1, 5.0000000000000000e-001 ]\n"
|
||||
" - [ 1, 2, 3, -1.5 ]\n"
|
||||
" - [ 2, 3, 4, 1.5 ]\n"
|
||||
" - [ 3, 2, 1, 0.5 ]\n"
|
||||
" -\n"
|
||||
" - [ 3, 2, 1, 5.0000000000000000e-001 ]\n"
|
||||
" - [ 1, 2, 3, -1.5000000000000000e+000 ]\n"
|
||||
" - [ 3, 2, 1, 0.5 ]\n"
|
||||
" - [ 1, 2, 3, -1.5 ]\n"
|
||||
);
|
||||
#else
|
||||
EXPECT_STREQ(fs_result.c_str(),
|
||||
"%YAML:1.0\n"
|
||||
"---\n"
|
||||
"dvv:\n"
|
||||
" -\n"
|
||||
" - [ 1, 2, 3, -1.5000000000000000e+00 ]\n"
|
||||
" - [ 2, 3, 4, 1.5000000000000000e+00 ]\n"
|
||||
" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n"
|
||||
" -\n"
|
||||
" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n"
|
||||
" - [ 1, 2, 3, -1.5000000000000000e+00 ]\n"
|
||||
);
|
||||
#endif
|
||||
#endif // OPENCV_TRAITS_ENABLE_DEPRECATED
|
||||
|
||||
cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
|
||||
@@ -1966,5 +1936,53 @@ TEST(Core_InputOutput, FileStorage_invalid_path_regression_21448_JSON)
|
||||
fs.release();
|
||||
}
|
||||
|
||||
// see https://github.com/opencv/opencv/issues/25073
|
||||
typedef testing::TestWithParam< std::string > Core_InputOutput_regression_25073;
|
||||
|
||||
TEST_P(Core_InputOutput_regression_25073, my_double)
|
||||
{
|
||||
cv::String res = "";
|
||||
double my_double = 0.5;
|
||||
|
||||
FileStorage fs( GetParam(), cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
|
||||
EXPECT_NO_THROW( fs << "my_double" << my_double );
|
||||
EXPECT_NO_THROW( fs << "my_int" << 5 );
|
||||
EXPECT_NO_THROW( res = fs.releaseAndGetString() );
|
||||
EXPECT_NE( res.find("0.5"), String::npos ) << res; // Found "0.5"
|
||||
EXPECT_EQ( res.find("5.0"), String::npos ) << res; // Not Found "5.000000000000000000e-01"
|
||||
fs.release();
|
||||
}
|
||||
|
||||
TEST_P(Core_InputOutput_regression_25073, my_float)
|
||||
{
|
||||
cv::String res = "";
|
||||
float my_float = 0.5;
|
||||
|
||||
FileStorage fs( GetParam(), cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
|
||||
EXPECT_NO_THROW( fs << "my_float" << my_float );
|
||||
EXPECT_NO_THROW( fs << "my_int" << 5 );
|
||||
EXPECT_NO_THROW( res = fs.releaseAndGetString() );
|
||||
EXPECT_NE( res.find("0.5"), String::npos ) << res; // Found "0.5"
|
||||
EXPECT_EQ( res.find("5.0"), String::npos ) << res; // Not Found "5.00000000e-01",
|
||||
fs.release();
|
||||
}
|
||||
|
||||
TEST_P(Core_InputOutput_regression_25073, my_float16)
|
||||
{
|
||||
cv::String res = "";
|
||||
cv::float16_t my_float16(0.5);
|
||||
|
||||
FileStorage fs( GetParam(), cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
|
||||
EXPECT_NO_THROW( fs << "my_float16" << my_float16 );
|
||||
EXPECT_NO_THROW( fs << "my_int" << 5 );
|
||||
EXPECT_NO_THROW( res = fs.releaseAndGetString() );
|
||||
EXPECT_NE( res.find("0.5"), String::npos ) << res; // Found "0.5".
|
||||
EXPECT_EQ( res.find("5.0"), String::npos ) << res; // Not Found "5.0000e-01".
|
||||
fs.release();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P( /*nothing*/,
|
||||
Core_InputOutput_regression_25073,
|
||||
Values("test.json", "test.xml", "test.yml") );
|
||||
|
||||
}} // namespace
|
||||
|
||||
Reference in New Issue
Block a user