@@ -484,6 +484,81 @@ GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);
484484GTEST_API_ void PrintTo (__int128_t v, ::std::ostream* os);
485485#endif // __SIZEOF_INT128__
486486
487+ // The default resolution used to print floating-point values uses only
488+ // 6 digits, which can be confusing if a test compares two values whose
489+ // difference lies in the 7th digit. So we'd like to print out numbers
490+ // in full precision.
491+ // However if the value is something simple like 1.1, full will print a
492+ // long string like 1.100000001 due to floating-point numbers not using
493+ // a base of 10. This routiune returns an appropriate resolution for a
494+ // given floating-point number, that is, 6 if it will be accurate, or a
495+ // max_digits10 value (full precision) if it won't, for values between
496+ // 0.0001 and one million.
497+ // It does this by computing what those digits would be (by multiplying
498+ // by an appropriate power of 10), then dividing by that power again to
499+ // see if gets the original value back.
500+ // A similar algorithm applies for values larger than one million; note
501+ // that for those values, we must divide to get a six-digit number, and
502+ // then multiply to possibly get the original value again.
503+ template <typename FloatType>
504+ int AppropriateResolution (FloatType val) {
505+ int full = std::numeric_limits<FloatType>::max_digits10;
506+ if (val < 0 ) val = -val;
507+
508+ if (val < 1000000 ) {
509+ FloatType mulfor6 = 1e10 ;
510+ if (val >= 100000.0 ) { // 100,000 to 999,999
511+ mulfor6 = 1.0 ;
512+ } else if (val >= 10000.0 ) {
513+ mulfor6 = 1e1 ;
514+ } else if (val >= 1000.0 ) {
515+ mulfor6 = 1e2 ;
516+ } else if (val >= 100.0 ) {
517+ mulfor6 = 1e3 ;
518+ } else if (val >= 10.0 ) {
519+ mulfor6 = 1e4 ;
520+ } else if (val >= 1.0 ) {
521+ mulfor6 = 1e5 ;
522+ } else if (val >= 0.1 ) {
523+ mulfor6 = 1e6 ;
524+ } else if (val >= 0.01 ) {
525+ mulfor6 = 1e7 ;
526+ } else if (val >= 0.001 ) {
527+ mulfor6 = 1e8 ;
528+ } else if (val >= 0.0001 ) {
529+ mulfor6 = 1e9 ;
530+ }
531+ if (static_cast <int32_t >(val * mulfor6 + 0.5 ) / mulfor6 == val) return 6 ;
532+ } else if (val < 1e10 ) {
533+ FloatType divfor6 = 1.0 ;
534+ if (val >= 1e9 ) { // 1,000,000,000 to 9,999,999,999
535+ divfor6 = 10000 ;
536+ } else if (val >= 1e8 ) { // 100,000,000 to 999,999,999
537+ divfor6 = 1000 ;
538+ } else if (val >= 1e7 ) { // 10,000,000 to 99,999,999
539+ divfor6 = 100 ;
540+ } else if (val >= 1e6 ) { // 1,000,000 to 9,999,999
541+ divfor6 = 10 ;
542+ }
543+ if (static_cast <int32_t >(val / divfor6 + 0.5 ) * divfor6 == val) return 6 ;
544+ }
545+ return full;
546+ }
547+
548+ inline void PrintTo (float f, ::std::ostream* os) {
549+ auto old_precision = os->precision ();
550+ os->precision (AppropriateResolution (f));
551+ *os << f;
552+ os->precision (old_precision);
553+ }
554+
555+ inline void PrintTo (double d, ::std::ostream* os) {
556+ auto old_precision = os->precision ();
557+ os->precision (AppropriateResolution (d));
558+ *os << d;
559+ os->precision (old_precision);
560+ }
561+
487562// Overloads for C strings.
488563GTEST_API_ void PrintTo (const char * s, ::std::ostream* os);
489564inline void PrintTo (char * s, ::std::ostream* os) {
0 commit comments