У меня есть программа, которая получает данные стороннего API, но иногда двойные значения, которые я получил, представлены в "неточном" (или слишком точном) способе, например.
0,3 - 0,2999999999999
0,04 представлены как 0.03999999999999
Это вызывает проблемы, особенно когда я хотел бы проводить сравнения сравнений. Есть ли способ очистить "неточность" двойных ценностей по мере их получения?
О чем я могу думать:
public Form1()
{
InitializeComponent();
double x = 0.2999999999999; //from third party API
x = cleanDouble(x); //x=0.3
}
private double cleanDouble(double input)
{
string s = input.ToString("0.##########");
double.TryParse(s, out input);
return input;
}
Есть ли более эффективный способ сделать это? Преобразование двойного в строку и обратно в двойное не кажется мне очень эффективным или элегантным.
Большое спасибо.
PS В целях моего применения точность значений, которые я получу, будет не более 0,00000001.
PPS Я не буду заранее знать, какую ценность я получу от стороннего API. Это может быть 0.0004999999999, 0.039999999999999, 100.049999999999999 и т.д.
PPPS Для этого вопроса мне нужно использовать double, а не decimal.
Я точно не знаю, как вы собираетесь с подобными данными, так что это может или не может применяться, но можете ли вы быть в безопасности только Math.Round(double, int)
? Это не совсем элегантно, это действительно больше, чем Band-Aid. Но если действительно нет способа очистить то, что вы втягиваете, это сработает.
Поскольку вы говорите, что не нужно превышать точность 0.00000001, вы можете просто сделать
Math.Round(value, 8);
Вы можете оставить номера в покое и написать свою собственную функцию сравнения. Что-то вроде:
Bool Test = IsRoughlyEqual(.0001, .0002, .01);
public bool IsRoughlyEqual(double NumA, double NumB, double Tolerance)
{
double Result = Math.Abs(NumA - NumB);
if (Result > Tolerance)
return false;
else
return true;
}
Это будет намного быстрее, чем преобразование double в строку, а затем перерассчитывание в double.
private double cleanDouble(double input)
{
double ceil = Math.Ceil(input);
if (ceil - input < 0.00000001)
return ceil;
double floor = Math.Floor(input);
if (input - floor < 0.00000001)
return floor;
return input;
}
Имейте в виду, что некоторые цифры не могут быть на 100% точнее представлены двойным, поэтому необходим определенный допуск.