2010-05-29 2 views
33

Что случилось с этим? Я делаю простое умножение:Не должно ли это переполнение? Это не так!

Int64 x = 11111111111; 
Int64 y = 11111111111; 
Int64 z = x * y; 

И в конце умножения, г показывает значение:

-5670418394979206991

Это явно переполнена, но исключение не возникает. Я бы хотел, чтобы один был поднят, но ...

Обратите внимание, что это на Windows Phone 7, но я не думаю, что это имеет какое-либо отношение к проблеме. Или это?

ответ

43

Вы можете использовать проверенный блок, как уже отмечалось другими ответами:

checked 
{ 
    long x = 11111111111; 
    long y = 11111111111; 
    long z = checked(x * y); 
    // ... 
} 

Какие результаты в виде исключения:

OverflowException: Арифметические операции привело к переполнению.

Если вы просто делаете одну операцию, где вы должны проверки вы можете использовать вместо checked expression:

long x = 11111111111; 
long y = 11111111111; 
long z = checked(x * y); 

Вы также можете установить /checked compiler option иметь значение по умолчанию будет проверяться.

Чтобы установить этот параметр компилятора в среде визуальной разработки Студия:

  1. Открыть диалоговое окно Property Pages проекта. Для получения дополнительной информации см. Setting Visual C# Project Properties.
  2. Нажмите Свойства конфигурации.
  3. Нажмите на странице недвижимости Build.
  4. Изменить Проверить свойство арифметического переполнения/нижнего слоя.

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

+25

Обратите внимание, что причина, по которой unchecked является значением по умолчанию, состоит в том, что (1) 99% от времени целочисленной арифметики нигде не находится вблизи границ, а (2) арифметика проверена медленнее. Это один из редких случаев, когда дизайн C# выбирает опасные по умолчанию по соображениям производительности. –

+0

x86 jitter использует простой jno, предсказание ветвей всегда хорошее, не может стоить больше, чем за один цикл. –

+0

Не то, чтобы это было обязательно связано с дизайном C#, но в этом конкретном случае мы говорим о ARM. Поведение джиттера x86 несколько академическое – Stewart

26

Check it:

checked 
{ 
    Int64 x = 11111111111; 
    Int64 y = 11111111111; 
    Int64 z = x * y; 
} 
+6

Бинго! Узнай что-то новое каждый день, я делаю! Благодарю. И благодарите доброту за СО. – Cyberherbalist

8

Try:

checked 
{ 
    Int64 x = 11111111111; 
    Int64 y = 11111111111; 
    Int64 z = x * y; 
} 
8

компилятор предполагает, что вы хотите сделать это таким образом, и приступить к переполнению. Если переполнение должно рассматриваться как исключение для операции, оберните операцию вокруг checked и она выкинет исключение во время выполнения.

checked 
{ 
    Int64 x = 11111111111; 
    Int64 y = 11111111111; 
    Int64 z = x * y; 
} 

System.OverflowException: исключение типа System.OverflowException был брошен.

Смежные вопросы