【问题标题】:why adding 1 to byte.MaxValue results in 256 not an overflow [duplicate]为什么将 1 添加到 byte.MaxValue 会导致 256 不是溢出 [重复]
【发布时间】:2019-07-19 15:00:09
【问题描述】:

我在 C# 中有一段简单的代码,用于在将类型的 MaxValue 添加 1 时显示溢出错误。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            byte a = byte.MaxValue;
            byte b = 1;
            Console.WriteLine("Max+1 is : {0}", a+b);

            Console.ReadLine();
        }
    }
}

但不是溢出和错误结果,而是生成正确的值:256 为什么? 而 C# 中字节变量的最大值为 255。 我错了吗?

【问题讨论】:

  • 为什么string str = (255 + 1).ToString();会抛出错误?
  • 添加byte c = a + b; 似乎深入了解了添加的完成方式:“无法将类型'int'隐式转换为'byte'。存在显式转换(您是否缺少cast?)" - 似乎 byte 被隐式转换为 int 以进行此添加。
  • 您只是添加这两个值并显示它们,而不是将它们分配给一个字节。
  • 当您添加字节时,它们会隐式转换为整数。查看stackoverflow.com/questions/941584/byte-byte-int-why

标签: c# overflow


【解决方案1】:

添加任何小于int 的内容都在int 中完成。这在 Numeric Promotions

下的 Standard ECMA-334 C# specification 中进行了描述

12.4.7 数字促销

当重载解决规则(§12.6.4)应用于这组 运算符,效果是选择第一个运算符 操作数类型存在哪些隐式转换。 [示例:对于 操作 b * s,其中 b 是一个字节,s 是一个短重载 resolution 选择运算符 *(int, int) 作为最佳运算符。因此, 效果是 b 和 s 被转换为 int,而 结果是整数。同样,对于操作 i * d,其中 i 是一个 int 并且 d 是一个 double,重载决议选择 operator *(double, double) 作为最佳算子。结束示例]

此外,如果您想捕获溢出,您将需要使用 checked 关键字

示例

byte a = byte.MaxValue;
byte b = 1;
byte c = checked((byte)(a + b));

其他资源

checked (C# Reference)

默认情况下,仅包含常量值的表达式会导致 如果表达式产生的值超出 目标类型的范围。如果表达式包含一个或多个 非常量值,编译器不会检测到溢出。 在以下示例中评估分配给 i2 的表达式 不会导致编译器错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    • 2014-12-20
    • 2018-10-11
    相关资源
    最近更新 更多