
为什么0.1 + 0.2 不等于 0.3?为什么16777216f 等于 16777217f?为什么金钱计算都推荐用decimal?本文主要学习了解一下数字背后不为人知的存储秘密。
01、数值类型
C#中的数字类型主要包含两类,整数、小数,C#中的小数都为浮点(小)数。

void Main()
{
int a1 = 100;
int a2 = 0x0f; //15
var b2 = 0b11; //3
var x1 = 1; //整数值默认为int
var y1 = 1.1; //小数值默认为double
Add(1, 2.3); //3.3
Add(1, 3); //4
}
private T Add<T>(T x, T y) where T : INumber<T>
{
return x + y * x;
}
- 用
var类型推断时,整数值默认为int,小数值默认为double。 .NET 7新增的一个专门用来约束数字类型的接口 INumber<T> ,用来约束数字类型非常好用。
数值类型大多提供的成员:
| 🔸静态字段 | 说明 |
|---|---|
| MaxValue | 最大值常量,Console.WriteLine(int.MaxValue); //2147483647 |
| MinValue | 最小值常量 |
| 🔸静态方法 | 说明 |
| Parse、TryParse | 转换为数值类型,是比较常用的类型转换函数,参数NumberStyles可定义解析的数字格式 |
| Max、Min | 比较值的大小,返回最大、小的值,int.Max(1,100) //100 |
| Abs | 计算绝对值 |
| IsInfinity | 是否有效值,无穷值 |
| IsInteger | 是否整数 |
| IsNaN | 是否为NaN |
| IsPositive | 是否零或正实数 |
| IsNegative | 是否表示负实数 |
数值类型还有很多接口,如加、减、乘、除的操作符接口,作为泛型约束条件使用还是挺不错的。
| 🔸操作符接口 | 说明 |
|---|---|
| IAdditionOperators | 加法 |
| ISubtractionOperators | 减法 |
| IMultiplyOperators | 乘法 |
| IDivisionOperators | 除法 |
public static T Power<T>(T v1, T v2) where T : INumber<T>,
IMultiplyOperators<T, T, T>, IAdditionOperators<T, T, T>
{
return v1 * v1 + v2 * v2;
}
02、小数、浮点数⁉
C#中的小数类型有float、double、decimal 都是浮点数,浮点 就是“ 浮动小数点位置”,小数位数不固定,小数部分、整数部分是共享数据存储空间的。相应的,自然也有定点小数,固定小数位数,在很多数据库中有定点小数,C#中并没有。
在编码中我们常用的浮点小数是float、double,经常会遇到精度问题,以及类似下面这些面试题。
- ❓ 为什么
0.1 + 0.2不等于0.3? - ❓ 为什么浮点数无法准确的表示
0.1? - ❓ 为什么
16777216f等于16777217f?这里f表示为float。 - ❓ 为什么
32位float可以最大表示3.402823E38,64位double可以最大表示1.79*E308,那么点位数根本存不下啊? - ❓ 同样是32位,
float的数据范围远超int,为什么?

Console.WriteLine(0.1 + 0.2 == 0.3); //False
Console.WriteLine(16777216f == 16777217f); //True
Console.WriteLine(double.MaxValue); //1.7976931348623157E+308
Console.WriteLine(int.MaxValue); //2147483647
Console.WriteLine(sizeof(double)); //8 //8字节(64位)
float、double为浮点数,小数位数有限,比较容易损失精度。造成上面这些问题的根本原因是其存储机制决定的,他们都遵循IEEE754格式规范,几乎所有编程语言和处理器都支持该规范,因此大多数编程语言都有类似的问题。Decimal 为高精度浮点数,存储机制与float、double不同,她采用十进制方式表示。
❗ 要搞懂float、double,就不得不了解IEEE754规范!
2.1、IEEE754:float、double存储原理
IEEE 754 (维基百科)是一个关于浮点数算术的国际标准,它定义了浮点数的表示格式、舍入规则、特殊值、浮点运算等规范。IEEE 754 标准最早发布与1985年,其中包括了四种精度规范,其中最常用的就两种:单精度(float,4字节32位)和双精度(double,8字节64位



被折叠的 条评论
为什么被折叠?



