Размер чисел, участвующих в вычислениях с плавающей запятой, не является самым важным. Это расчет, который выполняется, который имеет отношение к делу.
По сути, если вы выполняете вычисление, а результатом является иррациональное число или повторяющееся десятичное число, то при округлении этого числа в используемую вами структуру данных конечного размера будут возникать ошибки округления. Поскольку double в два раза больше числа с плавающей точкой, ошибка округления будет намного меньше.
В тестах могут быть специально использованы числа, которые могут вызвать такую ошибку, и поэтому проверено, что вы использовали соответствующий тип в своем коде.
Если вы не против привязки к реализации Microsoft, вы можете использовать эту функцию, определенную в
int _wcsnicmp(
const wchar_t *string1,
const wchar_t *string2,
size_t count
);
. Но если вам нужно наилучшее соотношение производительности / совместимости / функциональности вам, вероятно, придется взглянуть на библиотеку ускорения (в любом случае часть ее - stl). Простой пример (взят из другого ответа на другой вопрос):
#include <boost/algorithm/string.hpp>
std::wstring wstr1 = L"hello, world!";
std::wstring wstr2 = L"HELLO, WORLD!";
if (boost::iequals(wstr1, wstr2))
{
// Strings are identical
}
Если вам нужно, чтобы строка всегда выполняла сравнение без учета регистра (при использовании операторов == или! =), То возможное элегантное решение - переопределить метод char_traits :: compare.
Определите свою собственную структуру. Пример
struct my_wchar_traits: public std::char_traits< wchar_t>
{
static int compare( const char_type* op1, const char_type* op2, std::size_t num)
{
// Implementation here... any of the previous responses might help...
}
};
Затем определите свою собственную строку без учета регистра:
typedef std::basic_string< wchar_t, my_wchar_traits> my_wstring;
Кстати об английском? хотя я бы выбрал свой прекрасный Boost :)
bool isequal(const std::wstring& first, const std::wstring& second)
{
if(first.size() != second.size())
return false;
for(std::wstring::size_type i = 0; i < first.size(); i++)
{
if(first[i] != second[i] && first[i] != (second[i] ^ 32))
return false;
}
return true;
}
Использование стандартной библиотеки:
bool comparei(wstring stringA , wstring stringB)
{
transform(stringA.begin(), stringA.end(), stringA.begin(), toupper);
transform(stringB.begin(), stringB.end(), stringB.begin(), toupper);
return (stringA == stringB);
}
wstring stringA = "foo";
wstring stringB = "FOO";
if(comparei(stringA , stringB))
{
// strings match
}
Вы можете использовать библиотеку алгоритмов повышения строки. Это библиотека только для заголовков, если вы не собираетесь использовать регулярное выражение. Так что вы можете сделать это очень легко.
http://www.boost.org/doc/libs/1_39_0/doc/html/string_algo.html
Вы можете использовать std :: tolower ()
для преобразования строк в нижний регистр или использовать функцию wcscasecmp
, чтобы выполнить сравнение без учета регистра в c_str ()
.
Вот функтор сравнения, который вы также можете использовать напрямую:
struct ci_less_w
{
bool operator() (const std::wstring & s1, const std::wstring & s2) const
{
#ifndef _WIN32
return wcscasecmp(s1.c_str(), s2.c_str()) < 0;
#else
return _wcsicmp(s1.c_str(), s2.c_str()) < 0;
#endif
}
};
#include <algorithm>
#include <string>
#include <cstdio>
bool icase_wchar_cmp(wchar_t a, wchar_t b)
{
return std::toupper(a) == std::toupper(b);
}
bool icase_cmp(std::wstring const& s1, std::wstring const& s2)
{
return (s1.size() == s2.size()) &&
std::equal(s1.begin(), s1.end(), s2.begin(),
icase_wchar_cmp);
}
int main(int argc, char** argv)
{
using namespace std;
wstring str1(L"Hello"), str2(L"hello");
wprintf(L"%S and %S are %S\n", str1.c_str(), str2.c_str(),
icase_cmp(str1,str2) ? L"equal" : L"not equal");
return 0;
}
Вы можете использовать mismatch () или lexicographic_compare (). Это предлагает Скотт Мейерс в Effecitve STL, пункт 35.