【问题标题】:Multiplication in C# errorC#中的乘法错误
【发布时间】:2015-03-10 04:57:51
【问题描述】:

当乘以一组 int 并将结果转换为 long 时,我得到不同的答案,而不是当我乘以一组双精度并将结果转换为 long 时。例如:

int a = 5;
int b = 5;
int c = 7;
int d = 6;
int ee = 6;
int f = 8;
int g = 9;
int h = 6;
int i = 6;
int j = 4;
int k = 8;
int l = 9;
int m = 5;
long x = a * b * c * d * ee * f * g * h * i * j * k * l * m;

double aa = 5;
double ab = 5;
double ac = 7;
double ad = 6;
double aee = 6;
double af = 8;
double ag = 9;
double ah = 6;
double ai = 6;
double aj = 4;
double ak = 8;
double al = 9;
double am = 5;
long y = (long)(aa * ab * ac * ad * aee * af * ag * ah * ai * aj * ak * al * am);

谁能告诉我为什么会这样?谢谢

【问题讨论】:

  • 因为longdouble 是不同的东西
  • Double 和 float 不能以 100% 的精度保存任何数字,除非它是 2 的幂。相反,它们只保存 近似值..这就是为什么我们有小数
  • 我建议在您的项目设置中启用溢出检查(至少对于调试版本)。

标签: c# type-conversion multiplication


【解决方案1】:

你有一个整数溢出,因为每当你将两个int 相乘时,你就有int: 到目前为止,这被解释为Int32

 a * b * c * d * ee * f * g * h * i * j * k * l * m

并且仅转换为Int64 (long)。要更正实施,请声明 所有变量最初都是long 例如

  long a = 5;
  long b = 5; // actually, not necessary, since a * b will be long, but safer
  long c = 7;
  ...
  long m = 5;

  long x = a * b * c * d * ee * f * g * h * i * j * k * l * m;

【讨论】:

  • 甚至不需要将它们全部制作成long。只需“强制计算”即可:long z = (long)a * b * c * d * ee * f * g * h * i * j * k * l * m;
  • @ChrFin:你是对的,在这种情况下,从技术上讲,只有第一个参数必须是Int64类型;然而,当遇到整数溢出时,更安全的说法是:“我必须使用 64 位表示”并将所有整数参数转换为 Int64
  • @DmitryBychenko:谢谢,我以为是这样的。
【解决方案2】:

这可能是因为您的乘法结果太大而无法保存在 Int32 中 - 但它可以保存在双精度中。

更具体地看一下十六进制的 x 和 y:

x = 0x000000007994b000
y = 0x000000057994b000

Int32 只能保存低 8 个十六进制值。这就是为什么x 是错误的数字。最低的 8 个十六进制值是正确的,但顶部被截断。

【讨论】:

    【解决方案3】:

    我给它一个简短的搜索,甚至在脚本上也运行了一些测试,我发现了以下结果, 在脚本格式中,我将其测试为,

    <script>
            var a = 5;
            var b = 5;
            var c = 7;
            var d = 6;
            var ee = 6;
            var f = 8;
            var g = 9;
            var h = 6;
            var i = 6;
            var j = 4;
            var k = 8;
            var l = 9;
            var m = 5;
            var x = a * b * c * d * ee * f * g * h * i * j * k * l * m;
            var y = eval(a * b * c * d * ee * f * g * h * i * j * k * l * m);
            document.writeln("RESULT X : " + x);
            document.write("<br>");
            document.writeln("RESULT Y : " + y);
        </script>
    

    对于xy,结果都是23514624000,但是在c# 中,当您尝试将所有整数相乘时,结果会形成一个整数,但我们也知道int.MAX = 2147483647 小于thw实际结果,因此在分配给long x= a * b * c * d * ee * f * g * h * i * j * k * l * m; 的结果中,它会截断原始值,而在其他结果中则不是,如果您希望两者的结果相同,可以使用以下代码,

    int a = 5;
    int b = 5;
    int c = 7;
    int d = 6;
    int ee = 6;
    int f = 8;
    int g = 9;
    int h = 6;
    int i = 6;
    int j = 4;
    int k = 8;
    int l = 9;
    int m = 5;
    long x = (long)a * b * c * d * ee * f * g * h * i * j * k * l * m;
    
    double aa = 5;
    double ab = 5;
    double ac = 7;
    double ad = 6;
    double aee = 6;
    double af = 8;
    double ag = 9;
    double ah = 6;
    double ai = 6;
    double aj = 4;
    double ak = 8;
    double al = 9;
    double am = 5;
    long y = (long)(aa * ab * ac * ad * aee * af * ag * ah * ai * aj * ak * al * am);
    Console.WriteLine(x);
    Console.WriteLine(y);
    Console.ReadKey();
    

    现在您将得到相同的结果,即 23514624000

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-05
      • 2021-08-30
      • 2013-12-18
      • 1970-01-01
      • 1970-01-01
      • 2012-01-19
      • 2016-07-31
      • 1970-01-01
      相关资源
      最近更新 更多