为什么C#允许*Long隐式*从Long转换为Float,这可能会失去精度?

Ami*_*tal 20 .net c# floating-point implicit-conversion long-integer

一个类似的问题Long in Float,为什么?这里没有回答我在寻找的东西.

C#标准允许从long到float的隐式转换.但任何长于2 ^ 24的长度在表示为浮动时必然会失去其"价值".C#标准清楚地表明,长期浮动转换可能会失去"精确度",但永远不会失去"幅度".

我的问题是
  1. 关于积分类型,"精确"和"幅度"的含义.数字n与数字n + 1完全不同,与实数不同,其中3.333333和3.333329可能被认为足够接近计算(即取决于程序员想要的精度)
  2. 不允许隐式转换从long到浮动邀请到微妙的错误,因为它可能导致长期"默默地"失去价值(作为一个C#程序员,我习惯于编译器在防范这些问题方面做得非常出色)

那么C#语言设计团队允许这种转换是隐含的理由是什么呢?我在这里失踪的是什么证明从长期到浮动的隐性转换是正确的?

Ere*_*mez 11

这是一个很好的问题.实际上你可以概括这个问题,因为隐含转换存在同样的问题:

  • intfloat
  • uintfloat
  • longfloat(你问的问题)
  • ulongfloat
  • longdouble
  • ulongdouble.

事实上,所有整数类型(甚至char!!)都有隐式转换为floatdouble; 但是,只有上面列出的转换会导致精度损失.另一个有趣的事情是,在解释"为什么没有从十进制到双精度的隐式转换"时,C#语言规范有一个自相矛盾的参数:

十进制类型具有更高的精度,但比浮点类型的范围更小.因此,从浮点类型到十进制的转换可能会产生溢出异常,从十进制到浮点类型的转换可能会导致精度损失.由于这些原因,浮点类型和十进制之间不存在隐式转换,并且没有显式转换,不可能在同一表达式中混合浮点和十进制操作数.

我认为,"为什么做出这个决定"的问题最好由Eric Lippert这样的人来回答.我最好的猜测......这是语言设计者没有任何强烈争论的方式之一,所以他们选择(他们认为的)更好的替代方案,尽管这是有争议的.在他们的辩护中,当你将一个大的转换longfloat,你的精度是松散的,但你仍然得到浮点世界中这个数字的最佳表示.这就像转换intbyte可能存在溢出的地方(整数值可能超出byte可以表示的范围)并且得到不相关/错误的数字.但是,在我看来,decimal如果它们没有进行导致精度损失的其他转换,那么从没有隐式转换到浮点会更加一致.


ken*_*nny 8

通常,浮点数并不完全代表许多数字.就其本质而言,它们是不精确的并且容易出现精确错误.它确实没有增加价值来警告你浮点的情况总是如此.

  • 这太笼统而且不精确.在精度范围*内具有2的幂的所有整数和分数都是*精确表示的,因此说"它们不精确且受精度误差影响"是不正确的.另一个问题是整数到浮点转换*通常是正确的,因此它的错误是非常微妙的.反例:将32位整数转换为双倍精度,*始终*正确的结果. (6认同)