【问题标题】:Why .0 is dropped in division but not in +, - and *?为什么 .0 在除法中被删除,而不是在 +、- 和 * 中?
【发布时间】:2021-11-27 17:47:56
【问题描述】:

因此,根据 C# 规则,在除法(int & int 除法)中,输出是一个 int。在 (FP & int Division) 中,它是一个 FP。

但随后会产生不同的输出。

int a = 45; //integer
decimal b = 5.0m; //floating point
Console.WriteLine(a/b); // "9"

输出是:9 //输出看起来像一个整数???为什么?

请注意,+、- 和 * 会产生预期结果:

  Console.WriteLine(a * b); // "225.0"

除以非整数产生预期结果:

int a = 45; //integer
decimal b = 5.5m; //floating point
Console.WriteLine(a/b); // "8.181818181818181818"

输出是:8.181818181818181818 - / 输出是一个 FP,没关系。

谁能解释一下?

float / double 的结果更加一致 - 所有操作的输出中都没有零(这是有道理的,因为这些类型不存储小数点后位数的信息)

【问题讨论】:

  • output is an integer - 没有。输出是数字的字符串表示 - 在这两种情况下。如果您想要特定格式,请使用 string.Format() - 例如。另外:你期望输出是什么? 9.0? 9.00? 9.000? ...(提示:将除法的结果保存在变量中并使用调试器进行检查)
  • 我希望它是“9.0”,因为 5.0 是一个浮点数,就像 5.5 在不使用任何 string.Format() 的情况下以浮点数生成输出一样,我正在教我的学生“的一般规则”除法运算符”。但是,我不知道为什么它会在 9.0 P.S. 中截断零。我是一名教师,第一次教 C#。
  • 作为一名教师,您应该知道,在数学上,9 等于 9.09.00000000000000000000000000000000...。所以程序选择最短的。就像它打印5.5 而不是5.50000(或者,例如,05.5)。另外,我没有任何冒犯的意思,但我相信在教授 C# 之前更好地理解 C# 的基础知识是明智之举? C# documentation 是一个很好的起点。
  • @FranzGleichmann 请注意,问题中使用的decimal5m5.0m 不同 - 所以很公平的预期除法结果将保留“小数点后一位”。因此,虽然看起来绝对愚蠢,但这个问题实际上有充分的理由存在。
  • 我认为考虑“浮点”或“非浮点”值没有帮助。它们都是 all 浮点值。这是关于“保留多少有效数字”或“保留多少小数位”。

标签: c# .net integer decimal


【解决方案1】:

C# 标准在section 12.9.3 中详细介绍。

在进行任何舍入之前,结果的比例是与首选比例最接近的比例,它将保留与精确结果相等的结果。首选比例是x 的比例减去y 的比例。

因此,为了应用它,我们得到了值为 45m 的 x(在隐式转换为 decimal 之后),比例为 0,5.0m 的比例为 1。

因此,首选比例为 -1 - 这将是无效的。 (比例总是非负的。)可以保留精确结果的最接近的比例是 0,所以这是 实际 比例 - 结果相当于 9m 而不是 9.0m

【讨论】:

  • 很抱歉,如果您能在我的更新中查看示例 2 并解释为什么使用 45.0m 会得到 9.0 的结果,但在 PO 示例中使用 5.0m 会得到 9 的结果,那将是您的荣幸?
  • @Serge: 45.0 的比例为 1,5 的比例为 0,因此“首选比例”为 1,结果为 9.0。 (我已经解释了为什么 45/5.0 在答案中返回 9 - 这将有一个负的首选比例,所以它使用 0 作为最接近的有效比例,并且仍然给出正确的准确结果。)
  • 谢谢,我很抱歉我必须是假人,但我仍然不明白这一点,因为对我来说 PO 示例对我来说看起来一样 - 5.0m 有一个比例尺,45 有一个比例尺0,所以“首选比例”是 1,结果为 9.0,但结果为 9。唯一的区别是它们的角色相反。
  • 如果尝试 int a = 45;小数 b = 5.000m;你仍然会有 a/b=9,而不是 9.000
  • @Serge:您以错误的方式减去比例。首选比例是scale(x) - scale(y),因此 45/5.0 的首选比例是 -1,而不是 1。同样,45/5.000m 的首选比例是 -3
【解决方案2】:

我测试并得到了这个结果

int a = 45; //integer
    decimal b = 5.0m; //floating point
    var r=a/b; // r is decimal
    Console.WriteLine(r);  // 9


 a = 45; //integer
     b = 5.5m; //decimal floating point
     r=a/b;   // r is decimal
    Console.WriteLine(r);  // 8.181818181818181818181818182

正如我在调试器中看到的那样,两种情况下的输出都是十进制的,而不是第一种情况下的整数

如果代码中没有明确定义结果,编译器会进行隐式转换。有很多方法可以转换类型。这里的主要规则是“如果表达式中有多个操作数,则结果的类型是操作数类型中最大的”。例如,如果将 int 和 double 相除,则结果为 double。如果你把byte和int相乘,结果就是int。

更多示例(现在使用乘法)

    int a = 45; //integer
    
    decimal b = 5.0m; //floating point
    var rm = a*b; // rm is decimal
    Console.WriteLine(rm);  // 225.0
        
    b = 5.5m; //decimal floating point
    var r2m = a*b; // r2m is decimal
    Console.WriteLine(r2m);  // 247.5

更新

由于@AlexeiLevenkov 对问题进行了重大更改,并且他在 cmets 中问我为什么 .0 在除法中被删除,这些示例表明它不是真的

 int a = 5; //integer


 decimal b = 45m; //floating point
 var r= b/a; // r is decimal
Console.WriteLine(r);  //  9


 b = 45.0m; //floating point
  r= b/a; // r is decimal
Console.WriteLine(r);  //  9.0

 b = 45.00m; //floating point
 var r= b/a; // r is decimal
Console.WriteLine(r);  //  9.00

 b = 45.000m; //floating point
 var r= b/a; // r is decimal
Console.WriteLine(r);  //  9.000

这些示例表明,默认情况下,商的零值与被除数的数目一样多。

更新 2

如果你尝试这个,你会得到错误“不能隐式地将类型十进制转换为整数

int r = a/b; // error!!!

不过没关系

int r = a/(int)b; 

这也可以

decimal r = a/b; 

【讨论】:

  • 谢谢,我做到了,并得到了解决方案/了解为什么它会生成这样的输出。
  • 如果您添加对Console.WriteLine(a*b); 输出的解释,答案将非常棒......没有它,它实际上只是部分答案......即使@Amy 得到了他们想要的东西。
  • @AlexeiLevenkov 好的,再次检查我的答案
  • 这是一个例子而不是解释——没有理由为什么它打印“225.0”而不是像float 看到的“225”(如果真的有的话,我真的很感兴趣除法行为的正式解释......我可以合理地看到为什么其他操作保持小数精度)
  • @AlexeiLevenkov " 9 or 9.0 " 为什么它对你如此重要?我根本没有任何实际用途,对任何代码都没有任何影响
【解决方案3】:
int a = 45; //integer
decimal b = 5.0m; //floating point
Console.WriteLine(a/b); // why "9" and not 9.0 right?

如果我问你,你会用 5.0 乘以什么得到 45?你会说 9 还是 9.0?

通俗地说,商除非存在余数,否则保持整数。

现在让我们看看十进制有什么独特之处。

double x = 10.0d; // is 10

但是

decimal x = 10.0m; //is 10.0 

十进制公式:x.0m is x.0 and xm is x

double/float 的公式:x.0d or xd is x

现在应用上面的公式,看看这些案例......

10.0d + 10.0d + 10.0d ( x.0d is x )

10 + 10 + 10 = 30

10.0d + 10.1d + 10.0d ( x.0d is x )

10 + 10.1 + 10 = 30.1

45 * 5.0d ( x.0d is x )

45 * 5 = 255

但是……

10.0m + 10.0m + 10.0m ( x.0m is x.0 )

10.0 + 10.0 + 10.0 = 30.0

10.0m + 10.1m + 10.0m ( x.0m is x.0 )

10.0 + 10.1 + 10.0 = 30.1

45 * 5.0m ( x.0m is x.0 )

45 * 5.0 = 255.0

45 * 5m ( xm is x )

45 * 5 = 255

现在想想除法过程……

它的除数 * (quotient(0...+/-n)) 直到余数变为 0 或小于除数

45/5.0米

5.0m * 1m..2m..3m...9m 余数在此处变为 0。 结尾。最后商是 9m。

但是 9m 仍然是 9 而不是 9.0 对吧?

【讨论】:

  • 这真的很有趣,也很容易理解。非常感谢!
猜你喜欢
  • 2015-05-12
  • 1970-01-01
  • 2021-03-11
  • 2014-06-14
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多