Re: Попинайте арифметику
От: watchmaker  
Дата: 02.06.14 16:47
Оценка: 12 (1)
Здравствуйте, Marty, Вы писали:

M> Понадобилось тут немного арифметики, решил сам наваять,


Понадобилось? Зачем? Почему не подошло готовое?

M> дело вообщем-то нехитрое ;)

Ну и раз нехитрое, то что же код деления не привёл тогда? )

M> Использовал эту
Автор: Lorenzo_LAMAS
Дата: 12.04.12
тему.


Ну, видимо невнимательно прочитал ту тему. Вот например:
M>// returns true if carry detected
M>inline bool signed_addition( INT32 a, INT32 b, INT32 *c = 0 )
M>{
M>    INT32 r = a + b; if (c) *c = r; return !(b >= 0 == r >= a);
M>}
Переполнение для знаковых чисел — неопределённое поведение. Твоя проверка !(b >= 0 == r >= a) бессмысленна и неверна.
Компилятор, например, аналогично считает: http://goo.gl/2Gcbx4 — в результирующем кода функция всегда возвращает false. Ну и это очевидно почему так: если после сложения результат не вызвал переполнения, то возвращаем false. Если вызвал, то произошло UB и всё равно что функция будет возвращать, поэтому также возвращаем false, так как это не требует дополнительного кода. И оказывается, что от проверки ничего не зависит, и её можно смело игнорировать.


M>template<> bool integer_addition<INT16> (INT16  a, INT16  b, INT16  *c) { return signed_addition( a, b, c ); }
M>template<> bool integer_addition<INT16> (INT16  a, INT16  b, INT16  &c) { return signed_addition( a, b, c ); }
M>template<> bool integer_addition<INT32> (INT32  a, INT32  b, INT32  *c) { return signed_addition( a, b, c ); }
M>template<> bool integer_addition<INT32> (INT32  a, INT32  b, INT32  &c) { return signed_addition( a, b, c ); }
M>template<> bool integer_addition<INT64> (INT64  a, INT64  b, INT64  *c) { return signed_addition( a, b, c ); }
M>template<> bool integer_addition<INT64> (INT64  a, INT64  b, INT64  &c) { return signed_addition( a, b, c ); }

Кошмар. Шаблоны нужны чтобы избавиться от копипасты, а не чтобы сделать её в несколько раз больше. Ну вот зачем тебе тут специализация? Зачем вообще вызвать нешаблонные unsigned_addition из шаблонных integer_addition?
Я ещё понимаю, если бы ты разделял код для знаковых и беззнаковых типов (но даже для этого специализация не нужна), но вот это дублирование для всех размеров совсем ужасно.


M>template<typename IntT>
M>IntT integer_abs( IntT i )  { return (i<0) ? -i : /*return*/ i; }
Эта функция у тебя иногда возвращает отрицательный результат вследствие переполнения на минимальном целом.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.