c# - 为什么 C# 允许从 Long 到 Float 的*隐式*转换,而这可能会丢失精度?

标签 c# .net floating-point long-integer implicit-conversion

类似的问题Long in Float, why?这里没有回答我正在搜索的内容。

C# 标准允许从 long 到 float 的隐式转换。 但是当表示为 float 时,任何大于 2^24 的长度都必然会失去其“值(value)”。 C# 标准明确指出,long 到 float 的转换可能会失去“精度”,但绝不会失去“量级”。

我的问题是
  1. 在提到整数类型时,“精度”和“量级”是什么意思。数字 n 是否与数字 n+1 完全不同,不像实数,其中 3.333333 和 3.333329 可能被认为足够接近计算(即取决于程序员想要的精度)
  2. 不允许从 long 到 float 的隐式转换邀请到微妙的错误,因为它会导致 long ‘默默地’失去值(value)(作为一名 C# 程序员,我习惯于编译器在保护我免受此类问题的影响方面做得非常出色)

那么 C# 语言设计团队允许这种隐式转换的基本原理是什么?我在这里缺少什么来证明从 long 到 float 的隐式转换是合理的?

最佳答案

这是个好问题。实际上你可以概括这个问题,因为同样的问题存在于隐式转换:

  • intfloat
  • uintfloat
  • longfloat (你问的是什么)
  • ulongfloat
  • longdouble
  • ulongdouble .

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

The decimal type has greater precision but smaller range than the floating-point types. Thus, conversions from the floating-point types to decimal might produce overflow exceptions, and conversions from decimal to the floating-point types might cause loss of precision. For these reasons, no implicit conversions exist between the floating-point types and decimal, and without explicit casts, it is not possible to mix floating-point and decimal operands in the same expression.

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

关于c# - 为什么 C# 允许从 Long 到 Float 的*隐式*转换,而这可能会丢失精度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11183980/

相关文章:

c# - 将 UI 和 API 组合到单个 Blazor 服务器应用程序中?

c# - 在 MVC 模型中的何处初始化静态属性并实现锁

c# - C# 中的 MergeSort 实现

c# - 在未绑定(bind)的 DataGridView 中看不到行

c# - 我如何知道对象属性是否具有默认值?

.net - 与 .net 和 mono 一起使用的最佳对象关系映射框架?

.net - Web.config 转换可以与 App.config 文件一起使用吗?

Python 关于舍入的奇怪行为

c++ - 用浮点任意精度 C++ 库改造现有代码,有成功的机会吗?

c++ - 为什么int提升为double而不是float进行隐式转换