summaryrefslogtreecommitdiff
path: root/tools/aapt2/ResourceValues.cpp
diff options
context:
space:
mode:
author Brandon Liu <branliu@google.com> 2023-03-31 22:37:42 +0000
committer Brandon Liu <branliu@google.com> 2023-05-04 17:43:00 +0000
commitc674d38c8cea475cd29f7b0835e9864a2424b646 (patch)
treede281494f9e9bcbebc736eee1c0e6eba1cb8b9a4 /tools/aapt2/ResourceValues.cpp
parente1e4129f4fd3fc78a4bd2f6fe1018b436022376d (diff)
Add additional check on float precision after parsing, only compile the
value to a float when the difference between float and double parsed from same raw string is smaller than 1. Bug: b/69347762 Test: Verified affected atests pass and added new atest Change-Id: I25da0baccba580484db39aa2d0a1bb765706635d
Diffstat (limited to 'tools/aapt2/ResourceValues.cpp')
-rw-r--r--tools/aapt2/ResourceValues.cpp19
1 files changed, 18 insertions, 1 deletions
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
index a5754e0d168f..166b01bd9154 100644
--- a/tools/aapt2/ResourceValues.cpp
+++ b/tools/aapt2/ResourceValues.cpp
@@ -439,6 +439,21 @@ static std::string ComplexToString(uint32_t complex_value, bool fraction) {
return str;
}
+// This function is designed to using different specifier to print different floats,
+// which can print more accurate format rather than using %g only.
+const char* BinaryPrimitive::DecideFormat(float f) {
+ // if the float is either too big or too tiny, print it in scientific notation.
+ // eg: "10995116277760000000000" to 1.099512e+22, "0.00000000001" to 1.000000e-11
+ if (fabs(f) > std::numeric_limits<int64_t>::max() || fabs(f) < 1e-10) {
+ return "%e";
+ // Else if the number is an integer exactly, print it without trailing zeros.
+ // eg: "1099511627776" to 1099511627776
+ } else if (int64_t(f) == f) {
+ return "%.0f";
+ }
+ return "%g";
+}
+
void BinaryPrimitive::PrettyPrint(Printer* printer) const {
using ::android::Res_value;
switch (value.dataType) {
@@ -470,7 +485,9 @@ void BinaryPrimitive::PrettyPrint(Printer* printer) const {
break;
case Res_value::TYPE_FLOAT:
- printer->Print(StringPrintf("%g", *reinterpret_cast<const float*>(&value.data)));
+ float f;
+ f = *reinterpret_cast<const float*>(&value.data);
+ printer->Print(StringPrintf(DecideFormat(f), f));
break;
case Res_value::TYPE_DIMENSION: