Print infinities and NaNs, and numbers in a portable way. Goals: - portable (across IEEE 754 platforms) - shows all possible IEEE values - shows simple numbers in a simple way, e.g., no leading/trailing 0s - shows all digits, no premature rounding
| 1112 | // - shows simple numbers in a simple way, e.g., no leading/trailing 0s |
| 1113 | // - shows all digits, no premature rounding |
| 1114 | static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraOutput extra) |
| 1115 | { |
| 1116 | if (std::isinf(value)) { |
| 1117 | if (value < 0) |
| 1118 | out.debug << "-1.#INF"; |
| 1119 | else |
| 1120 | out.debug << "+1.#INF"; |
| 1121 | } else if (std::isnan(value)) |
| 1122 | out.debug << "1.#IND"; |
| 1123 | else { |
| 1124 | const int maxSize = 340; |
| 1125 | char buf[maxSize]; |
| 1126 | const char* format = "%f"; |
| 1127 | if (fabs(value) > 0.0 && (fabs(value) < 1e-5 || fabs(value) > 1e12)) |
| 1128 | format = "%-.13e"; |
| 1129 | int len = snprintf(buf, maxSize, format, value); |
| 1130 | assert(len < maxSize); |
| 1131 | |
| 1132 | // remove a leading zero in the 100s slot in exponent; it is not portable |
| 1133 | // pattern: XX...XXXe+0XX or XX...XXXe-0XX |
| 1134 | if (len > 5) { |
| 1135 | if (buf[len-5] == 'e' && (buf[len-4] == '+' || buf[len-4] == '-') && buf[len-3] == '0') { |
| 1136 | buf[len-3] = buf[len-2]; |
| 1137 | buf[len-2] = buf[len-1]; |
| 1138 | buf[len-1] = '\0'; |
| 1139 | } |
| 1140 | } |
| 1141 | |
| 1142 | out.debug << buf; |
| 1143 | |
| 1144 | switch (extra) { |
| 1145 | case TOutputTraverser::BinaryDoubleOutput: |
| 1146 | { |
| 1147 | uint64_t b; |
| 1148 | static_assert(sizeof(b) == sizeof(value), "sizeof(uint64_t) != sizeof(double)"); |
| 1149 | memcpy(&b, &value, sizeof(b)); |
| 1150 | |
| 1151 | out.debug << " : "; |
| 1152 | for (size_t i = 0; i < 8 * sizeof(value); ++i, ++b) { |
| 1153 | out.debug << ((b & 0x8000000000000000) != 0 ? "1" : "0"); |
| 1154 | b <<= 1; |
| 1155 | } |
| 1156 | break; |
| 1157 | } |
| 1158 | default: |
| 1159 | break; |
| 1160 | } |
| 1161 | } |
| 1162 | } |
| 1163 | |
| 1164 | static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion, |
| 1165 | TOutputTraverser::EExtraOutput extra, int depth) |
no outgoing calls
no test coverage detected