Переполнение вопросов на поплавке и поплавках × целые числа

StackOverflow https://stackoverflow.com/questions/3438476

Вопрос

1) Это unoverflowable?

long long v1, v2, result;
[..]
result = ((long double) v1 / v2) * 1000000LL;

1.a) Могу ли я оставить LL на постоянной? И почему.

2) В качестве альтернативы это вариация без поплавка в порядке?

long long l1, l2, result;
[..]
result = (1000000 * (v1 / v2) + v1 % v2);

2.a) У кого больше накладных расходов? 1 или этот пример?

3) Может ликать когда-либо переполненные или просто обернуть к значению «Sane»?

Это было полезно?

Решение

Да, результат в примере (1) может легко переполнить, если, скажем, v1 = 1000000000000000 и v2 = 1. Вам не нужна LL на этой константе, потому что она достаточно мала, чтобы вписаться в int (при большинстве реализаций, в любом случае).

(2) Это может переполнить так же, как и пример 1, если V1 и V2, как я их дал.

Первым примером более дороже, так как арифметика с плавающей точкой является дороже, чем целочисленная арифметика.

(3) Поплавки могут, безусловно, переполнение, и последствия зависят от реализации.

Как указал Arjit, вы можете предотвратить переполнение, проверив значение V1, прежде чем выполнять расчет. Если V1 может быть отрицательным, вам также нужно будет проверить отрицательную версию, и, возможно, следующее может быть лучше ...

if ((LONG_LONG_MAX / 1000000) > V1)
{
...
}

Если вы на самом деле против лимита, вы могли бы дать себе немного больше запасов, объявляя переменные быть unsigned.

Позже - редактировать, чтобы исправить ошибку, указанную Arjit.

Другие советы

во-первых

  1. Если делать INT или длительный расчет, не включайте поплавок к нему. Потому что ваш результат в первой части будет иметь много разных ценностей, которые почти равны.

Потому что (float) v1 / v2 = ab.cdef. // где CDEF может варьироваться.

Ваша вторая реализация также может вызвать переполнение, если v1 = 2 ^ 15 и v2 = 1

так что если вы ищете переполнение и безопасность, вы всегда должны проверять

Как 2 ^ 18 / константа, что в этом случае 1000000

так

if(2^18/Constant > v1)

    result = (1000000 * (v1 / v2) + v1 % v2);

Это будет любое доказательство взлома.

Надеюсь это поможет

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top