C#.Net筑基-深入解密小数内部存储的秘密

image.png

为什么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
  • ❓ 为什么32float可以最大表示3.402823E3864double可以最大表示1.79*E308,那么点位数根本存不下啊?
  • ❓ 同样是32位,float的数据范围远超int,为什么?

image.png

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值