C#对于非数字double.NaN的神奇现象,无穷大的处理以及整数除以0 您所在的位置:网站首页 如何判断double的值是不是0 C#对于非数字double.NaN的神奇现象,无穷大的处理以及整数除以0

C#对于非数字double.NaN的神奇现象,无穷大的处理以及整数除以0

2024-07-14 18:17| 来源: 网络整理| 查看: 265

某次执行小数除以0时,发现居然不抛出异常。执行如下代码片段:

try { Console.WriteLine(Math.Sqrt(-4)); int num = 0; Console.WriteLine(10.5F / num); } catch (Exception ex) { Console.WriteLine($"浮点运算出现异常:{ex.Message}"); } Console.ReadLine();

原本以为会抛出异常,尝试运行下,出现戏剧的一幕,

一般来说,字符串为中文时,转换为double类型的转换结果都为false

【double.TryParse("中文",out result)】

但运行如下代码:

Console.WriteLine(double.TryParse("非数字",out double result));

 运行结果:

查看微软对小数点的逻辑时,小数除以0用不抛出异常。

 但某个小数与double.NaN 比较,结果一定为false

即使非数字与double.NaN比较,仍然为false

某个数字除以0的处理 类别除以0的结果中文描述比较与运算处理负数double.NegativeInfinity负无穷大可以进行比较,运算结果为负无穷或者非数字0double.NaN非数字比较永远为false,运算结果永远为NaN(非数字)正数double.PositiveInfinity正无穷大可以进行比较,运算结果为正无穷或者非数字

微软定义:

当未定义算术运算时,Double.NaN 表示非数字结果。 测试一个值与 Double.NaN 之间的相等关系的任何表达式始终返回 false。 测试一个值与 Double.NaN 之间的不等关系的任何表达式始终返回 true。

如何解决冲突。若要修复与此规则的冲突并准确确定某个值是否表示 Double.NaN,请使用 Single.IsNan 或 Double.IsNan 来测试值。

但整数不能尝试除以0,否则将抛出异常 DivideByZeroException。

尝试将整数或 System.Decimal 值除以零时引发的异常。

浮点数值类型(C# 引用)

浮点数值类型表示实数。 所有浮点型数值类型均为值类型。 它们还是简单类型,可以使用文本进行初始化。 所有浮点数值类型都支持算术、比较和相等运算符。

浮点类型的特征

C# 支持以下预定义浮点类型:

浮点类型的特征 C# 类型/关键字大致范围精度大小.NET 类型float±1.5 x 10−45 至 ±3.4 x 1038大约 6-9 位数字4 个字节System.Singledouble±5.0 × 10−324 到 ±1.7 × 10308大约 15-17 位数字8 个字节System.Doubledecimal±1.0 x 10-28 至 ±7.9228 x 102828-29 位16 个字节System.Decimal

在上表中,最左侧列中的每个 C# 类型关键字都是相应 .NET 类型的别名。 它们是可互换的。 

每个浮点类型的默认值都为零,0。 每个浮点类型都有 MinValue 和 MaxValue 常量,提供该类型的最小值和最大有限值。 float and double 类型还提供可表示非数字和无穷大值的常量。 例如,double 类型提供以下常量:Double.NaN、Double.NegativeInfinity 和 Double.PositiveInfinity。

当所需的精度由小数点右侧的位数决定时,decimal 类型是合适的。 此类数字通常用于财务应用程序、货币金额(例如 $1.00)、利率(例如 2.625%)等。 精确到只有一个小数的偶数用 decimal 类型处理会更准确:例如,0.1 可以由 decimal 实例精确表示,而没有精确表示 0.1 的 double 或 float 实例。 由于数值类型存在这种差异,因此当你对十进制数据使用 double 或 float 时,算术计算可能会出现意外的舍入错误。 当优化性能比确保准确度更重要时,可以使用 double 代替 decimal。 然而,除了大多数计算密集型应用程序之外,所有应用程序都不会注意到性能上的任何差异。 避免使用 decimal 的另一个可能原因是为了最大限度地降低存储需求。 例如,ML.NET 使用 float,因为对于非常大的数据集,4 个字节与 16 个字节之间的差异合乎情理。 有关详细信息,请参阅 System.Decimal。

真实文本

真实文本的类型由其后缀确定,如下所示:

不带后缀的文本或带有 d 或 D 后缀的文本的类型为 double带有 f 或 F 后缀的文本的类型为 float带有 m 或 M 后缀的文本的类型为 decimal

测试程序 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MagicFloatDemo { class Program { static void Main(string[] args) { Console.SetWindowSize(120, 50); Console.WriteLine("任何浮点数与double.NaN比较(大于、小于、等于)永远返回false。对【非数字】的任何运算(加减乘除等)都将返回NaN"); Console.WriteLine("【非数字NaN】必须是0除以0,非零除以0将返回无穷大"); Console.WriteLine("非零数除以0的结果:" + double.IsNaN(-8.00 / 0)); Console.WriteLine($"测试NaN的比较和运算结果:{double.NaN == double.NaN}"); Console.WriteLine($"测试NaN的比较和运算结果:{double.PositiveInfinity > double.NaN}"); Console.WriteLine("判断一个浮点数是否是【非数字】只能用 double.IsNaN(d)方法"); Console.WriteLine($"对非数字运算测试:{double.NaN + 5},结果是否是【非数字】:{double.IsNaN(double.NaN + 5)}"); Console.WriteLine("但正无穷【PositiveInfinity】和负无穷【NegativeInfinity】可以与其他浮点数比较"); Console.WriteLine($"两个负无穷比较:{double.NegativeInfinity == double.NegativeInfinity}"); Console.WriteLine($"正负无穷比较:{double.PositiveInfinity > double.NegativeInfinity}"); Console.WriteLine($"无穷与普通浮点数比较:{ double.PositiveInfinity > 55}"); Console.WriteLine($"无穷与普通浮点数比较:{double.NegativeInfinity > -888}"); Console.WriteLine($"判断一个结果是否为无穷大:{double.IsNegativeInfinity(-8.56 / 0)}"); Console.WriteLine($"正无穷与负无穷相加结果为NaN:{double.PositiveInfinity + double.NegativeInfinity}"); Console.WriteLine($"两个无穷相加:{double.PositiveInfinity + double.PositiveInfinity}"); Console.WriteLine($"正无穷减去正无穷:{double.PositiveInfinity - double.PositiveInfinity}"); Console.WriteLine($"正无穷普通运算:{double.PositiveInfinity - 3000.5}"); Console.WriteLine($"负无穷减去负无穷:{double.NegativeInfinity - double.NegativeInfinity}"); Console.WriteLine($"正无穷普通运算:{double.NegativeInfinity + 5E12D}"); Console.WriteLine("----测试字符串转化为浮点数----"); JudgeParse("非数字"); JudgeParse("负无穷大"); JudgeParse("正无穷大"); JudgeParse("无穷大"); JudgeParse("非数字123"); JudgeParse(""); JudgeParse("12345.6789"); JudgeParse("1.5E3"); JudgeParse("NaN"); JudgeParse("NegativeInfinity"); JudgeParse("Infinity"); JudgeParse("-123.45678E+3"); JudgeParse("\x39\u003645.E-2"); JudgeParse("-55"); JudgeParse(".643"); JudgeParse("."); JudgeParse("895."); double d = Math.Sqrt(-1); //非数字比较 永久为false 【d == double.NaN】 Console.WriteLine($"获取负数的平方根将不产生异常,按非数字处理:{d}.当前值与非数字比较结果:【{d == double.NaN}】,是否不为数字【{double.IsNaN(d)}】"); Console.WriteLine($"反正弦结果:【{Math.Asin(2)}】"); Console.WriteLine(); Console.WriteLine("整数int和十进制数decimal不能尝试除以0,否则将抛出异常。而浮点数可以除以0,返回NaN"); int x = 0; try { Console.WriteLine(8888.66M / x); } catch (Exception ex) { Console.WriteLine($"【{ex.GetType()}】{ex.Message}"); } try { Console.WriteLine(8848 / x); } catch (Exception ex) { Console.WriteLine($"【{ex.GetType()}】{ex.Message}"); } Console.WriteLine("----打印特殊值【非数字、无穷大】对应的字节数组----"); Console.WriteLine("Float非数字对应的字节数组:" + string.Join(",", BitConverter.GetBytes(float.NaN))); Console.WriteLine("Float负无穷对应的字节数组:" + string.Join(",", BitConverter.GetBytes(float.NegativeInfinity))); Console.WriteLine("Float正无穷对应的字节数组:" + string.Join(",", BitConverter.GetBytes(float.PositiveInfinity))); Console.WriteLine("Double非数字对应的字节数组:" + string.Join(",", BitConverter.GetBytes(double.NaN))); Console.WriteLine("Double负无穷对应的字节数组:" + string.Join(",", BitConverter.GetBytes(double.NegativeInfinity))); Console.WriteLine("Double正无穷对应的字节数组:" + string.Join(",", BitConverter.GetBytes(double.PositiveInfinity))); Console.ReadLine(); } /// /// 判断转换某一个字符串为双精度浮点数是否成功,以及返回结果 /// /// static void JudgeParse(string str) { double result; bool parseResult = double.TryParse(str, out result); Console.WriteLine($"操作是否成功【{parseResult}】,转换结果【{result}】,源字符串【{str}】"); } } } 运行结果:

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有