$NetBSD$ --- libraries/source/fcollada/src/FCollada/FUtils/FUStringBuilder.hpp.orig 2008-09-07 22:13:25.000000000 +0000 +++ libraries/source/fcollada/src/FCollada/FUtils/FUStringBuilder.hpp @@ -26,62 +26,6 @@ #define SAFE_DELETE_ARRAY(ptr) if (ptr != NULL) { delete [] ptr; ptr = NULL; } #endif -template -void FloatToString(FloatType f, Char* sz) -{ - Char* buffer = sz + 1; - static const int digitCount = 6; - int decimal, sign; - - // ecvt rounds the string for us: http://www.datafocus.com/docs/man3/ecvt.3.asp - char* end = ecvt(f, digitCount, &decimal, &sign); - - if (sign != 0) (*buffer++) = '-'; - int count = digitCount; - if (decimal > digitCount) - { - // We use the scientific notation: P.MeX - (*buffer++) = (*end++); // P is one character. - (*buffer++) = '.'; - - // Mantissa (cleaned for zeroes) - for (--count; count > 0; --count) if (end[count - 1] != '0') break; - for (int i = 0; i < count; ++i) (*buffer++) = (*end++); - if (buffer[-1] == '.') --buffer; - - // Exponent - (*buffer++) = 'e'; - uint32 exponent = decimal - 1; // X - if (exponent >= 10) (*buffer++) = (Char) ('0' + (exponent / 10)); - (*buffer++) = (Char) ('0' + (exponent % 10)); - (*buffer) = 0; - return; - } - else if (decimal > 0) - { - // Simple number: A.B - for (int i = 0; i < decimal; ++i) (*buffer++) = (*end++); - if (decimal < digitCount) (*buffer++) = '.'; - count = digitCount - decimal; - } - else if (decimal < -digitCount) - { - // What case is this? - decimal = count = 0; - } - else if (decimal < 0 || (decimal == 0 && *end != '0')) - { - // Tiny number: 0.Me-X - (*buffer++) = '0'; (*buffer++) = '.'; - for (int i = 0; i < -decimal; ++i) (*buffer++) = '0'; - count = digitCount + decimal; - } - for (; count > 0; --count) if (end[count - 1] != '0') break; - for (int i = 0; i < count; ++i) (*buffer++) = (*end++); - if (decimal == 0 && count == 0) (*buffer++) = '0'; - if (buffer[-1] == '.') --buffer; - (*buffer) = 0; -} template FUStringBuilderT::FUStringBuilderT(const String& sz) @@ -234,53 +178,46 @@ void FUStringBuilderT::append(cons template void FUStringBuilderT::append(float f) { -#ifdef WIN32 - // use _isnan method to detect the 1.#IND00 NaN. - if (f != std::numeric_limits::infinity() && f != -std::numeric_limits::infinity() && f != std::numeric_limits::quiet_NaN() && f != std::numeric_limits::signaling_NaN() && !_isnan((double)f)) -#else - if (f != std::numeric_limits::infinity() && f != -std::numeric_limits::infinity() && f != std::numeric_limits::quiet_NaN() && f != std::numeric_limits::signaling_NaN()) -#endif - { - if (IsEquivalent(f, 0.0f, std::numeric_limits::epsilon())) append((Char)'0'); - else - { - Char sz[128]; - FloatToString(f, sz); - append(sz + 1); - } - } - else if (f == std::numeric_limits::infinity()) - { append((Char)'I'); append((Char)'N'); append((Char)'F'); } - else if (f == -std::numeric_limits::infinity()) - { append((Char)'-'); append((Char)'I'); append((Char)'N'); append((Char)'F'); } - else - { append((Char)'N'); append((Char)'a'); append((Char)'N'); } + append((double)f); } template void FUStringBuilderT::append(double f) { -#ifdef WIN32 - // use _isnan method to detect the .#IND00 NaN. - if (f != std::numeric_limits::infinity() && f != -std::numeric_limits::infinity() && f != std::numeric_limits::quiet_NaN() && f != std::numeric_limits::signaling_NaN() && !_isnan(f)) -#else - if (f != std::numeric_limits::infinity() && f != -std::numeric_limits::infinity() && f != std::numeric_limits::quiet_NaN() && f != std::numeric_limits::signaling_NaN()) -#endif - { - if (IsEquivalent(f, 0.0, std::numeric_limits::epsilon())) append((Char)'0'); - else - { - Char sz[128]; - FloatToString(f, sz); - append(sz + 1); - } - } - else if (f == std::numeric_limits::infinity()) - { append((Char)'I'); append((Char)'N'); append((Char)'F'); } - else if (f == -std::numeric_limits::infinity()) - { append((Char)'-'); append((Char)'I'); append((Char)'N'); append((Char)'F'); } - else - { append((Char)'N'); append((Char)'a'); append((Char)'N'); } + if (f == -std::numeric_limits::infinity()) { + append("-INF"); + return; + } else if (f == std::numeric_limits::infinity()) { + append("INF"); + return; + } else if (f != f) { + append("NaN"); + return; + } else if (-std::numeric_limits::epsilon() < f && f < std::numeric_limits::epsilon()) { + append("0.0E0"); + return; + } + if (f < 0.0) { + f = -f; + append('-'); + } + + int e = 0; + if (f < 1.0) + for (; f < 1.0; f *= 10.0) + e--; + else + for (; f >= 10.0; f /= 10.0) + e++; + + char tmp[10]; + sprintf(tmp, "%.6g", f); + append(tmp); + if (tmp[1] == 0) // only one digit, add missing part according canonical representation + append(".0"); + + sprintf(tmp, "E%d", e); + append(tmp); } template