Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
895
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
906
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4351
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Сравнивая IEEE float и Double на равенство
Каков наилучший метод сравнения IEEE поплавков и двойников для равенства? Я слышал о нескольких методах, но мне хотелось узнать, что думает сообщество.
Я думаю, что лучший подход-это сравнить ULPs .
bool is_nan(float f)
{
return (*reinterpret_cast<unsigned __int32*>(&f) & 0x7f800000) == 0x7f800000 && (*reinterpret_cast<unsigned __int32*>(&f) & 0x007fffff) != 0;
}
bool is_finite(float f)
{
return (*reinterpret_cast<unsigned __int32*>(&f) & 0x7f800000) != 0x7f800000;
}
// if this symbol is defined, NaNs are never equal to anything (as is normal in IEEE floating point)
// if this symbol is not defined, NaNs are hugely different from regular numbers, but might be equal to each other
#define UNEQUAL_NANS 1
// if this symbol is defined, infinites are never equal to finite numbers (as they're unimaginably greater)
// if this symbol is not defined, infinities are 1 ULP away from +/- FLT_MAX
#define INFINITE_INFINITIES 1
// test whether two IEEE floats are within a specified number of representable values of each other
// This depends on the fact that IEEE floats are properly ordered when treated as signed magnitude integers
bool equal_float(float lhs, float rhs, unsigned __int32 max_ulp_difference)
{
#ifdef UNEQUAL_NANS
if(is_nan(lhs) || is_nan(rhs))
{
return false;
}
#endif
#ifdef INFINITE_INFINITIES
if((is_finite(lhs) && !is_finite(rhs)) || (!is_finite(lhs) && is_finite(rhs)))
{
return false;
}
#endif
signed __int32 left(*reinterpret_cast<signed __int32*>(&lhs));
// transform signed magnitude ints into 2s complement signed ints
if(left < 0)
{
left = 0x80000000 - left;
}
signed __int32 right(*reinterpret_cast<signed __int32*>(&rhs));
// transform signed magnitude ints into 2s complement signed ints
if(right < 0)
{
right = 0x80000000 - right;
}
if(static_cast<unsigned __int32>(std::abs(left - right)) <= max_ulp_difference)
{
return true;
}
return false;
}
Аналогичную технику можно использовать и для двойников. Хитрость заключается в том, чтобы преобразовать поплавки так, чтобы они были упорядочены (как целые числа), а затем просто посмотреть, насколько они отличаются.
Я понятия не имею, почему эта чертова штука портит мои подчеркивания. Edit: о, возможно, это просто артефакт предварительного просмотра. Тогда это OK.
Текущая версия которую я использую это
bool is_equals(float A, float B,
float maxRelativeError, float maxAbsoluteError)
{
if (fabs(A - B) < maxAbsoluteError)
return true;
float relativeError;
if (fabs(B) > fabs(A))
relativeError = fabs((A - B) / B);
else
relativeError = fabs((A - B) / A);
if (relativeError <= maxRelativeError)
return true;
return false;
}
Это, по-видимому, решает большинство проблем, сочетая относительную и абсолютную погрешность. Является ли подход ULP лучше? Если да, то почему?
@DrPizza: я не гуру производительности, но я бы ожидал, что операции с фиксированной точкой будут быстрее, чем операции с плавающей точкой (в большинстве случаев).
@DrPizza: я не гуру производительности, но я бы ожидал, что операции с фиксированной точкой будут быстрее, чем операции с плавающей точкой (в большинстве случаев).
Это скорее зависит от того, что вы делаете с ними. Тип с фиксированной точкой с тем же диапазоном, что и поплавок IEEE, будет во много раз медленнее (и во много раз больше).
Вещи подходящие для поплавков:
3D графика, physics/engineering, моделирование, моделирование климата....
В числовом программном обеспечении часто требуется проверить, являются ли два числа с плавающей запятой точно равными. LAPACK полон примеров для таких случаев. Конечно, наиболее распространенный случай-это когда вы хотите проверить, равно ли число с плавающей запятой "Zero", "One", "Two", "Half". Если кто-то заинтересован, я могу выбрать некоторые алгоритмы и перейти более подробно.
Кроме того, в BLAS вы часто хотите проверить, является ли число с плавающей запятой точно нулем или единицей. Например, подпрограмма dgemv может вычислять операции формы
- г = beta*y + alpha*A*x
- г = beta*y + alpha*A^T*x
- г = beta*y + alpha*A^H*x
Поэтому, если бета равна единице, у вас есть "plus assignment", а для бета равна нулю a "simple assignment". Таким образом, вы, безусловно, можете сократить вычислительные затраты, если вы дадите этим (общим) случаям специальное лечение.
Конечно, вы можете спроектировать подпрограммы BLAS таким образом, чтобы избежать точных сравнений (например, используя некоторые флаги). Однако LAPACK полон примеров, когда это невозможно.
P.S.:
Есть, конечно, много случаев, когда вы не хотите проверять на "is exactly equal". Для многих людей это даже может быть единственным случаем, с которым им когда-либо приходилось иметь дело. Все, что я хочу отметить, это то, что есть и другие случаи.
Хотя LAPACK написано в Fortran логика та же, если вы используете другие языки программирования для численного программного обеспечения.
О Боже, пожалуйста, не интерпретируйте плавающие биты как ints, если вы не работаете на P6 или раньше.
О Боже, пожалуйста, не интерпретируйте плавающие биты как ints, если вы не работаете на P6 или раньше.
Даже если это заставляет его копировать из векторных регистров в целочисленные регистры через память, и даже если он блокирует конвейер, это лучший способ сделать это, с которым я столкнулся, поскольку он обеспечивает наиболее надежные сравнения даже перед лицом ошибок с плавающей запятой.
то есть это цена, которую стоит заплатить.
Это, по-видимому, решает большинство проблем, сочетая относительную и абсолютную погрешность. Является ли подход ULP лучше? Если да, то почему?
Это, по-видимому, решает большинство проблем, сочетая относительную и абсолютную погрешность. Является ли подход ULP лучше? Если да, то почему?
ULPs-это прямая мера "distance" между двумя числами с плавающей запятой. Это означает, что они не требуют, чтобы вы вызывали относительные и абсолютные значения ошибок, и вам не нужно обязательно получать эти значения "about right". С помощью функции ULPs вы можете напрямую выразить, насколько близки вы хотите, чтобы числа были, и тот же порог работает так же хорошо для малых значений, как и для больших.
Если у вас есть ошибки с плавающей точкой, у вас есть еще больше проблем, чем это. Хотя я думаю, что это зависит от личной перспективы.
Если у вас есть ошибки с плавающей точкой, у вас есть еще больше проблем, чем это. Хотя я думаю, что это зависит от личной перспективы.
Даже если мы проведем численный анализ, чтобы минимизировать накопление ошибок, мы не сможем устранить их, и мы можем остаться с результатами, которые должны быть идентичными (если бы мы вычисляли с реалами), но различаться (потому что мы не можем вычислять с реалами).
Если вы ищете два поплавка, чтобы быть равными, то они должны быть одинаково равны, на мой взгляд. Если вы столкнулись с проблемой округления с плавающей точкой, возможно, представление с фиксированной точкой лучше подойдет для вашей проблемы.
Если вы ищете два поплавка, чтобы быть равными, то они должны быть одинаково равны, на мой взгляд. Если вы столкнулись с проблемой округления с плавающей точкой, возможно, представление с фиксированной точкой лучше подойдет для вашей проблемы.
Возможно, мы не можем позволить себе потерю дальности или производительности, которую может вызвать такой подход.
Если вы ищете два поплавка, чтобы быть равными, то они должны быть одинаково равны, на мой взгляд. Если вы столкнулись с проблемой округления с плавающей точкой, возможно, представление с фиксированной точкой лучше подойдет для вашей проблемы.
Если вы ищете два поплавка, чтобы быть равными, то они должны быть одинаково равны, на мой взгляд. Если вы столкнулись с проблемой округления с плавающей точкой, возможно, представление с фиксированной точкой лучше подойдет для вашей проблемы.
Возможно, мне следует лучше объяснить эту проблему. В C++ используется следующий код:
#include <iostream>
using namespace std;
int main()
{
float a = 1.0;
float b = 0.0;
for(int i=0;i<10;++i)
{
b+=0.1;
}
if(a != b)
{
cout << "Something is wrong" << endl;
}
return 1;
}
выводит фразу "Something is wrong". Вы хотите сказать, что так и должно быть?
@DrPizza: я не гуру производительности, но я бы ожидал, что операции с фиксированной точкой будут быстрее, чем операции с плавающей точкой (в большинстве случаев).
@Craig H: Конечно. Я полностью согласен с этим печатанием. Если a или b хранят деньги, то они должны быть представлены в фиксированной точке. Я изо всех сил пытаюсь придумать пример реального мира, где такая логика должна быть связана с поплавками. Вещи подходящие для поплавков:
- веса
- ранги
- далекие расстояния
- реальные мировые ценности (например, от A ADC)
Для всех этих вещей либо вы много затем вычисляете и просто представляете результаты пользователю для человеческой интерпретации, либо вы делаете сравнительное утверждение (даже если такое утверждение: "эта вещь находится в пределах 0.001 от этой другой вещи"). Сравнительное утверждение, подобное моему, полезно только в контексте алгоритма: часть" внутри 0.001 " зависит от того, какой физический вопрос вы задаете. Это мой 0.02. Или я должен сказать 2/100ths?
Это скорее зависит от того, кем вы являетесь
занимаюсь с ними. Тип фиксированной точки
с тем же диапазоном, что и поплавок IEEE
было бы во много раз медленнее (и
во много раз больше).
Это скорее зависит от того, кем вы являетесь занимаюсь с ними. Тип фиксированной точки с тем же диапазоном, что и поплавок IEEE было бы во много раз медленнее (и во много раз больше).
Хорошо, но если я хочу бесконечно малое битовое разрешение, то оно возвращается к моей исходной точке: = = и != не имеют никакого значения в контексте такой проблемы.
Int позволяет мне выразить значения ~10^9 (независимо от диапазона), которые кажутся достаточными для любой ситуации, когда я забочусь о том, чтобы два из них были равны. А если этого недостаточно, используйте 64-битный OS, и у вас будет около 10^19 различных значений.
Я могу выразить значения в диапазоне от 0 до 10^200 (например) в int, это просто бит-разрешение, которое страдает (разрешение будет больше 1, но, опять же, ни одно приложение не имеет такого диапазона, а также такого разрешения).
Подводя итог, я думаю, что во всех случаях одно или другое представляет собой континуум ценностей, и в этом случае != и == не имеют значения, либо один из них представляет фиксированный набор значений, которые могут быть сопоставлены с int (или другим типом фиксированной точности).
Int позволяет мне выразить значения ~10^9
(независимо от диапазона) который кажется
вроде достаточно для любой ситуации, где я
будет заботиться о том, чтобы двое из них были
равный. А если этого будет недостаточно, используйте
64-битный OS и у вас есть около 10^19
уникальное значение.
Int позволяет мне выразить значения ~10^9 (независимо от диапазона) который кажется вроде достаточно для любой ситуации, где я будет заботиться о том, чтобы двое из них были равный. А если этого будет недостаточно, используйте 64-битный OS и у вас есть около 10^19 уникальное значение.
Я действительно достиг этого предела... Я пытался жонглировать временем в ps и временем в тактовых циклах в симуляции, где вы легко нажмете 10^10 циклов. Что бы я ни делал, я очень быстро переполнил ничтожный диапазон 64-битных целых чисел... 10^19-это не так много, как вы думаете, дайте мне 128 бит вычислений сейчас!
Поплавки позволили мне получить решение математических вопросов, так как значения переполнялись множеством нулей в нижнем конце. Таким образом, у вас в основном была десятичная точка с плавающей точкой aronud в числе без потери точности (мне бы хотелось с более ограниченным определенным количеством значений, разрешенных в мантиссе float по сравнению с 64-битным int, но отчаянно необходимым диапазоном th!).
А затем вещи преобразуются обратно в целые числа для сравнения и т. д.
Раздражает, и в конце концов я отказался от всей попытки и просто полагался на поплавки и < и >, чтобы сделать работу. Не идеально, но работает для предусмотренного случая использования.