Какой самый быстрый способ написать совместимое с IEEE-754 двойное / плавающее деление на C ++?

Я хочу написать совместимое с IEEE-754 деление на C ++, особенно в отношении деления на ноль: positive/0->Inf, negative/0->-Inf, everything else/0->NaN,

В то время как простое разделение C ++ на моей машине В результате такого поведения стандарт C ++ не предписывает эту семантику. Вместо этого он не определен, поэтому я не могу на него полагаться.

Так какой же самый быстрый способ реализовать это в C ++? Конечно, я могу сделать явный тест, как это:

double fdiv64(double numerator, double denominator)
{
using limits=std::numeric_limits<double>;
if (denominator==0.0) {
if (numerator>0.0) {
return limits::infinity();
} else if (numerator<0.0) {
return -limits::infinity();
} else {
return limits::quiet_NaN();
}
} else {
return numerator/denominator;
}
}

Но это приводит к появлению дополнительных веток и совершенно излишне на моей машине, так как я все равно получаю правильное поведение на нем. Кажется, не существует встроенного компилятора, который бы соответствовал IEEE-754-совместимому разделению. Я мог бы использовать встроенную сборку, но это тоже непереносимо.

Так какой же самый быстрый способ сделать это разделение?

3

Решение

Боюсь, вы не сможете сделать это мобильно, если вы не создадите свою собственную реализацию IEEE754 с плавающей запятой в программном обеспечении для платформ, которые не используют его изначально, и даже в этом случае будут небольшие различия, поскольку ваш тип не будет встроенный тип (например, && а также || не будет короткого замыкания, если вы их перегружаете); хотя пользовательские литералы может помочь

Например, поддержка infinity является необязательным и присутствует на платформе только в том случае, если std::numeric_limits<T>::has_infinity == true для вашего типа T,

Так что попытки оптимизировать ваш якобы переносимый код даже не на столе.

Рекомендации:

http://en.cppreference.com/w/cpp/types/numeric_limits/infinity
http://en.cppreference.com/w/cpp/language/user_literal

4

Другие решения

Вы можете уже иметь это, не делая ничего особенного. На нескольких архитектурах вы можете указать, что ЦП должен делать в «особых» ситуациях (деление на ноль и т. Д.). Посмотри на fesetenv, Компиляторы обычно имеют переключатели о том, как они должны обрабатывать математические вычисления с плавающей точкой. Например, посмотрите на cl.exe в Visual Studio вариант об этом.

Если вы остаетесь на архитектуре x86 (и используете SSE или x87 с внутренней точностью, установленной на float / double, подробности смотрите по ссылкам ниже), я думаю, что вы можете положиться на поведение IEEE754 из коробки (поэтому ваша программа будет работать на любом x86 машина, а не только твоя).

Если у вас есть процессор, который не может следовать IEEE754, то вам, возможно, придется использовать полную программную реализацию с плавающей запятой. Или, может быть, вы можете использовать HW, и вам нужно только обрабатывать исключительные случаи.

Но обычно сегодня почти все (ПК, мобильные устройства) используют IEEE754:

В реализации SW вы должны извлечь знак, экспоненту, мантиссу из числа с плавающей запятой и выполнить математику самостоятельно.

Примечание. Вы можете получить результат inf, даже если делитель не ноль, а небольшое (субнормальное) число. Это потому, что макс. число для числа с плавающей точкой находится в диапазоне ~ 10 ^ 38, но минимальное, но положительное число находится в диапазоне ~ 10 ^ -45.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector