Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么可以';你不能直接给十进制类型分配一个带小数点的数字,而不使用类型后缀吗?_C# - Fatal编程技术网

C# 为什么可以';你不能直接给十进制类型分配一个带小数点的数字,而不使用类型后缀吗?

C# 为什么可以';你不能直接给十进制类型分配一个带小数点的数字,而不使用类型后缀吗?,c#,C#,为什么不能在不使用类型后缀的情况下直接将带有小数点的数字分配给十进制类型?这种数字不算是十进制数吗 decimal bankBalance = 3433.20; // ERROR! 编辑:我可能错过了问题的最后一部分,因此下面的概述几乎没有什么用处 不管怎么说,您之所以不能执行您试图执行的操作,是因为浮点类型和decimal之间没有隐式转换。但是,您可以从整数赋值,因为存在从int到decimal的隐式转换 可以,但必须使用此语法(或显式转换为十进制) 而对于浮子来说,它是 float ba

为什么不能在不使用类型后缀的情况下直接将带有小数点的数字分配给十进制类型?这种数字不算是十进制数吗

decimal bankBalance = 3433.20; // ERROR!

编辑:我可能错过了问题的最后一部分,因此下面的概述几乎没有什么用处

不管怎么说,您之所以不能执行您试图执行的操作,是因为浮点类型和
decimal
之间没有隐式转换。但是,您可以从整数赋值,因为存在从int到decimal的隐式转换


可以,但必须使用此语法(或显式转换为十进制)

而对于浮子来说,它是

float bankBalance = 3433.20f;
默认值为双倍

double bankBalance = 3444.20;
这个

会有用的。原因是浮点和十进制是非常不同的类型。float将为您输入的数字提供非常接近的近似值,但decimal将为您提供精确的数字。99%的时候你不会注意到差异,应该使用float

请参阅MSDN页面,该页面解释了正常浮点类型和十进制类型之间没有隐式转换

试一试


十进制银行余额=3433.20m

实际上,隐藏的规范功能:您可以-p

decimal bankBalance = (decimal)3433.20;
编译器将其真正解析为十进制(而不是浮点和强制转换)。请参阅IL以证明这一点。但是请注意,精度会被截断(它有1个十进制数字,而不是从
M
版本中得到的2个)

生成的IL:

L_0001: ldc.i4 0x861c
L_0006: ldc.i4.0 
L_0007: ldc.i4.0 
L_0008: ldc.i4.0 
L_0009: ldc.i4.1 
L_000a: newobj instance void [mscorlib]System.Decimal::.ctor(int32, int32, int32, bool, uint8)
L_000f: stloc.0 
与之相比:

decimal bankBalance = 3433.20M;
由此产生:

L_0001: ldc.i4 0x53d18
L_0006: ldc.i4.0 
L_0007: ldc.i4.0 
L_0008: ldc.i4.0 
L_0009: ldc.i4.2 
L_000a: newobj instance void [mscorlib]System.Decimal::.ctor(int32, int32, int32, bool, uint8)
L_000f: stloc.0 

唯一的区别是小数位数(1对2,相应的系数为10)

您的答案包括两个要点:

  • 所有带小数点的数字文字都被C#编译器推断为
    double
    类型,因此,
    3433.20
    默认为
    double

  • double
    数字不会隐式转换为
    decimal
    ,因为尽管
    decimal
    double
    更精确,但它覆盖的范围较短,因此从double转换为decimal时可能出现溢出

  • decimal bankBalance = 3433.20m;
    
    double
    的范围:
    ±(~10^−324到10^308)
    带有15或16个有效数字


    decimal
    的范围:
    ±(~10^-28到10^28)
    有28或29个有效数字。

    我们是否都错过了问题的最后一部分,还是刚刚添加了?正如我和其他人所说,原因是没有进行隐式类型转换。如果输入3433.20,则默认情况下为浮动。C#不会将浮点转换为十进制。我不知道他们为什么做出这个决定,但MSDN表明了这一点。我下面的答案有MSDN的链接,他们在那里解释了这一点。真的是一个字面小数吗?或者它只是像它看起来的那样转换一个双精度?我不完全确定(我没有检查),但我猜这将生成一个从双精度转换为十进制的运行时转换。它实际上是一个十进制。看IL,我刚检查了IL,你是对的。虽然奇怪的是只有一个十进制数字。。。我确实用Mono C#编译器测试了它,所以它可能是C#语言规范的一部分,“银行余额”和其他货币值在这1%的情况下。正确,但显式转换并不能让imo更容易阅读,但你是对的。“m”代表什么?@ThePoet
    d
    后缀已经被
    double
    ,所以他们决定用
    m
    表示
    deciMal
    。请看:否决票,虽然更多的信息总是有用的,但你没有回答他的问题question@ThePoet,问题的答案正是因为该类型不被视为十进制,而是双精度,它的范围比十进制更广,并且由于可能的数据丢失而无法隐式地分配给它(事实上很不幸,较高的答案没有提到这一点来告诉人们为什么你应该明确地包含后缀)。答案中包含了这一点,所以我相信这比回答问题更重要。
    L_0001: ldc.i4 0x53d18
    L_0006: ldc.i4.0 
    L_0007: ldc.i4.0 
    L_0008: ldc.i4.0 
    L_0009: ldc.i4.2 
    L_000a: newobj instance void [mscorlib]System.Decimal::.ctor(int32, int32, int32, bool, uint8)
    L_000f: stloc.0