检查多个数字是否溢出

时间:2016-01-07 16:15:56

标签: c++ integer-overflow

检测溢出时遇到问题。 我应该创建一个读取int c的程序,然后输入n对数字,这些数字应该相乘。数字乘以之后你需要检查它是否是整数溢出。如果它是's' s没有溢出打印数字成倍增加。

在c ++中;

以下是一个例子:

  

输入:3 2147483647和2147483647

     

18446744073709551615和2

     

666013和1

输出:

<Window x:Class="MyProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyProject"
        mc:Ignorable="d"
        Title="MainWindow" Width="800" Height="600">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Menu Grid.Row="0" IsMainMenu="True" Height="20" VerticalAlignment="Top">
            //menu items
        </Menu>
        <Grid Grid.Row="1" HorizontalAlignment="Stretch" Background="#FFF0F0F0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <StackPanel Grid.Column="1" Grid.Row="0" Orientation="Horizontal" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                <Button Content="Button1" HorizontalAlignment="Left" Padding="10,2" VerticalAlignment="Center"/>
                <Button Content="Button2" HorizontalAlignment="Left" Padding="10,2" VerticalAlignment="Center" Margin="10,0,0,0"/>
            </StackPanel>
            <DataGrid Grid.Column="1" 
                      Grid.Row="1" 
                      AutoGenerateColumns="False" 
                      IsReadOnly="False" 
                      CanUserResizeColumns="True" 
                      CanUserAddRows="True" 
                      CanUserSortColumns="True" 
                      ItemsSource="{Binding}" 
                      SelectionMode="Single" 
                      HeadersVisibility="Column" 
                      HorizontalContentAlignment="Stretch" 
                      VerticalContentAlignment="Stretch" 
                      BorderThickness="0" 
                      Margin="0" 
                      GridLinesVisibility="Horizontal"
                      ScrollViewer.CanContentScroll="True" 
                      ScrollViewer.HorizontalScrollBarVisibility="Visible" >
                <DataGrid.Columns>
                    //10 columns here
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
</Window>

1 个答案:

答案 0 :(得分:1)

你陷入了试图使用结果测试是否存在溢出的陷阱。事实上,你无法做到这一点。有符号整数溢出有不确定的行为,所以一旦发生,你已经搞砸了。您必须在操作之前使用操作数检查是否过低。

max为最大可表示整数。假设操作数是正数,a * b当且仅当a * b > max溢出时才会溢出。但是您无法执行该测试,因为如果a * b溢出,则结果无法使用。此外,我们知道没有整数大于max,因此测试总是错误的。

那么,我们如何在不使用a * b的结果的情况下使用该等式?我们将使用数学的魔力,最终得到一个等价的等式:a > max / b。我们只使用整数除法运算符,它不会溢出,很好!现在,方程的等价仅在b != 0时成立。试图划分max / 0将是一个错误。但是,我们知道任何a * 0 a都不会溢出,所以我们可以轻而易举地实现这一特殊情况。

所以,我们拥有的是:

int a, b;
// don't forget to initialize
if(b && a > INT_MAX / b)
    // overflow, abort!
else
    // no overflow, proceed

这仅适用于正输入。我将把它作为练习留给读者来实现所有整数的测试。