C#浮点文字:为什么编译器不默认为左侧变量类型

本文关键字:默认 类型 变量 编译器 文字 为什么 | 更新日期: 2023-09-27 18:28:42

要声明浮点数,我们需要为浮点数输入"f",为双精度数输入"d"。

例:

float num1 = 1.23f;   // float stored as float
float num2 = 1.23;    // double stored as float. The code won't compile in C#.

据说如果省略浮点文本,C# 默认为双精度。

我的问题是,是什么阻止了像"C#"到左侧变量类型的"DEFAULTS"这样的现代语言?毕竟,编译器可以看到整行代码。

这是出于编译器设计中的历史原因吗?还是我没有得到的东西。

C#浮点文字:为什么编译器不默认为左侧变量类型

我想

说主要原因是可预测性和一致性。

假设您是编译器,您必须在以下语句中确定文字3.14的类型:


float p = 3.14;

第一个很容易。显然,应该是一个浮动。


这个呢?

var x = 3.14 * 10.0f;

用户在 10.0 之后显式添加了f。所以这应该是一个float,什么关于3.14x应该是double还是float


而这个:

bool b = 3.14 / 3.14f == 1;

第一个3.14double还是floatb的价值取决于它!


作为用户,我宁愿明确添加一个f确切地知道我得到了什么。

这里的其他人可能会解释为什么 .NET 开发人员决定不使用某种预测来确定如何将数字文本硬塞到您提供给它的类型中。但在没有任何哲学的情况下,答案很简单:他们不想那样做,所以他们没有。我不会告诉你你完全不应该关心这个,因为当然,希望编译器准确理解你想要什么并不是完全不合理的。这至少会很好,对吧?

(不过,如果我不得不猜测,我会说这与允许某种逻辑隐式类型有很大关系 - float f = 1.0 float,但var d = 1.0 double?当你考虑到f.Equals(d(是false时,这就更不合逻辑了,尽管事实上1.0 == 1.0true

但是,假设他们有充分的理由不引入任何特定于类型定义的预测(一些更完美的理由可以在 Rotem 的帖子中找到(,我可以想象他们决定double num1 = 1.23是可以接受的,而float num1 = 1.23不是,坦率地说,double在大多数情况下更有用。在大多数用例中,使用 64 位浮点值而不是 32 位浮点值的 CPU 和 IO 损失可以忽略不计,但不必担心超出该数据类型的边界非常有用。

请注意,您可以就为什么不能将1.23分配给没有后缀的decimal提出完全相同的论点。设计C#的人认为对任何给定格式的数字文字的类型做出假设更容易,double是一个完全合理的假设,因为大多数编写1.23的人都想要一个double,或者至少应该使用一个。

编辑:用户固定标题。

因为你提出的功能基本上会使编译器不一致。规则简单易懂:3.14double3.14ffloat

的例子是微不足道的,但你看小图:

float x = 3.14;

好吧,假设编译器足够"智能",可以将文字解析为浮点数。

double x = 3.14;

嗯,现在同一个文字是一个double,没有从floatdouble的隐式转换......奇怪。那么以下类型应该是什么?

var x = 3.14;

同一问题的其他类似变体:

int i = 2 * 3.14;

编译时错误应该是什么?无法将double隐式转换为intfloat转换为int。为什么一个会比另一个更好?

var x = 2 * 3.14;

哦,哦,现在怎么办?

C# 设计人员决定将十进制数文本解析为double...总是。如果你想要另一种类型(floatdecimal(,你需要明确指定它。优点:一致性。他们本可以很好地决定将float为隐式类型,但你不能同时拥有它而不弄得一团糟。

此外,请务必注意,C# 解析规则(类型、方法等(始终忽略表达式左侧的类型。您的功能将使编译器根据左侧的类型更改其类型解析,这也与语言的行为方式不一致。