【问题标题】:C# "Integral constant is too large" - Integer variable too large for Int32 typeC#“积分常数太大” - Int32 类型的整数变量太大
【发布时间】:2018-03-04 08:42:28
【问题描述】:

我正在构建一个 ASP.NET Core API,它返回元素周期表和太阳系中的行星。主要是玩 API 调用,以及 .NET 中的数据类型。在 Visual Studio 2017 中构建它。

我在使用行星的质量属性时遇到问题,以千克为单位。显然是一个大整数,所以我尝试将其声明为 long、Ulong、Int64 甚至 UInt64。但是,当我尝试输入新的行星模型并输入质量时,出现以下错误:

struct System.Int32
Represents a 32 bit signed integer.
Integral constant is too large.

这是我描述属性的 PlanetModel.cs:

...
public UInt64 Volume { get; set; } //In Kilometers
public Int64 Mass { get; set; } //In Kilograms
public float Gravity { get; set; } //In m/s^2
...

然而,当我转到我的 PlanetDataStore.cs 时,我正在尝试使用数据构建对象。

new PlanetModel()
                {
                    Position = 1,
                    Name = "Mercury",
                    Distance = 57909050, //In Kilometers
                    Orbit = 0.240846F, //In years
                    SolarDay = 0.5F, //In Days
                    Radius = 2439, //In Kilometers
                    Volume = 60830000000, // In Kilometers
                    Mass = 330110000000000000000000, //In Kilograms
                    Gravity = 3.7F, //In m/s^2
                },

我在弥撒中的第一个“3”上出现了一个红色错误,上面的错误。然而,当我将鼠标悬停在质量上时,它显示:“long PlanetMode.Mass {get; set;} 当我将鼠标悬停在等号上时,它显示:“struct System.Int64”

哪里有误会?为什么我的属性声明为 64 位整数,但值却停留在 32 位?

【问题讨论】:

  • //以年=> //以地球年:)
  • 哈哈,是的。此时不会使用数据本身。该项目一直在试验如何在 .NET API 环境中使用对象、数据和 CRUD。我正在学习它,而我在 Java、JS 和 Go 方面只有一点经验。

标签: c# asp.net integer integer-overflow


【解决方案1】:

显然是一个大整数

这绝不是显而易见的。地球的质量不是千克的整数数。您不应该为此应用程序使用任何整数类型。对真正整数的事物使用整数,例如序列中元素的数量。

double 用于精确测量到小数点后十位的物理量。质量、体积、长度、力等等,都应该是两倍。

这也可以让您摆脱那些难以阅读的数字。双打可让您使用科学记数法,因为双打用于科学

Mass = 3.3011E23,

另外,在我们研究您的解决方案时,我注意到对于球形行星,可以根据半径计算体积。您可能不想同时存储两者;相反,只需存储一个并在需要时计算另一个。

我还注意到,在水星的情况下,您只有一个“距离”,这似乎是半长轴。为什么只存储半长轴,为什么不叫它是什么?

我还注意到,您在所有地方都混淆了您的单位——米和公里,天和年,等等。为什么不将所有内容都保存在标准单位中?米代表长度,秒代表时间,公斤代表质量。你会发现,当你始终使用标准单位时,你犯的愚蠢的算术错误会更少。

【讨论】:

  • 不会因为浮点运算不准确而导致 double 仍然有问题吗?既然 double 只能容纳 64 位数字?
  • @maccettura:你真的相信地球的质量正好 330110000000000000000000公斤吗?还是您认为其中可能存在一些错误,大约为 10000000000000000000 公斤左右?如果您愿意在初始估计中容忍 10000000000000000000 公斤的误差,那么您为什么担心会出现微小的浮点误差测量误差可能比浮点表示误差十个数量级。担心重要的错误!
  • 我并没有批评您的回答,我看到您的声誉得分很高,并想问一个问题。在我所做的工作中,我从来不需要存储/计算如此大的数字。我对浮点数的问题/不准确性了解有限,所以我想我会问作为一个学习机会。
  • @maccettura:那么你问这个问题是个好主意。担心浮点错误的原因是当您尝试表示精确的十进制算术时 - 例如,金融计算,其中$123.45 需要精确 123.45 ,而不是123.449999999999998。对于 C# 中的财务计算,请使用 decimal;它精确到小数点后 29 位,并且没有小数的表示错误。将double 用于物理 问题,在这些问题中量级很大但精度有限。
  • 我已将您的回复标记为@EricLippert,因为我很欣赏有关使用科学记数法以及处理科学数据的实践的答案和建议。我纯粹是在网上寻找基本数据,因为我只是想玩数据和 Web API。一旦我的练习完成,这些数据将没有真正的实际用途。不过,现在我知道问题出在哪里,如何输入科学记数法,以及更好地理解小数类型。
【解决方案2】:

正如其他人指出的那样,您的数字太大而无法适应 UInt64 结构。 因此,您将需要 BigInteger,或者可能是另一种更广泛、可变的数字类型,例如 double。所以你的模型像这样声明Mass 属性:

public double Mass { get; set; } //In Kilograms

接下来,您必须在数字文字后面加上 D,如下所示:

Mass = 330110000000000000000000D, //In Kilograms

您像往常一样格式化显示的数字:

mercury.Mass.ToString("N0");

【讨论】:

    【解决方案3】:

    对于 Int64,您拥有的值太长,long 也是 64 位。您可以在 Int64 中存储的最大数字是 (2^64 - 1)/2 = 9,223,372,036,854,775,807

    您可以将此数字存储为浮点数。如果要将数字存储为浮点数,则必须告诉编译器它是浮点数。

    查看浮点数的存储方式以获得更好的理解。如果你想把它存储在一个浮点数中,你可以这样做 330110000000000000000000.0f

    【讨论】:

    • 我不明白为什么即使您在进行计算也不想使用浮点数。如果你想要更高的精度,你可以使用小数。
    【解决方案4】:

    我不确定你从哪里获得结构和类型信息,但即使在Int64,该值也只是too largeInt64.MaxValue 是:

    9223372036854775807
    

    你有:

    330110000000000000000000
    

    即使是无符号的,数量级也太大了。你可以使用something like BigInteger instead

    【讨论】:

      【解决方案5】:

      C#中长文字必须以L为后缀

      Mass = 123456789012345L
      

      虽然这显然不能让您在 long 中存储大于 64 位的数字 :)

      为什么不使用浮点类型?

      【讨论】:

      • @kblok 答案被否决,因为 OP 的数量大于 Int64/UInt64 的最大值。如果您想亲眼看看,请参阅here
      【解决方案6】:

      这里有个小问题,Int64/UInt64 的最大值远小于您尝试分配的数字。

      从角度来看:

      330,110,000,000,000,000,000,000   //Your number
      9,223,372,036,854,775,807         //Int64 Max Value
      18,446,744,073,709,551,615        //UInt64 Max Value
      

      您的数字对于该数据类型来说太大了。

      虽然我对它的经验为零,但如果您使用 .NET 4.0 或更高版本,您也许可以使用BigInteger

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-29
        • 1970-01-01
        • 2015-01-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多