在工作中我发现了一个C#浮点数的精度问题,以下的程序运行结果并未得到我预期的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | namespace FloatTest { class Program { static void Main( string [] args) { double a = 0.0001; float b = 0.1F; int c = ( int )((a * 1000) / b); Console.WriteLine( "c = {0}" , c); Console.ReadLine(); } } } |
我期望的结果是得到1,结果程序返回的结果为c = 0
这让我想到了可能是因为浮点数采用IEEE754的表示方法,在运算中b会转换成double,可能是在转换中算法的问题导致精度丢失,为了证实该问题,我做了下面的实验:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | namespace FloatTest { class Program { static void Main( string [] args) { double a = 0.0001; float b = 0.1F; int c = ( int )((a * 1000) / b); Console.WriteLine( "a = {0}" , a); Console.WriteLine( "b = {0}" , Convert.ToDouble(b)); Console.WriteLine( "c = {0}" , c); Console.ReadLine(); } } } |
这次果然得到了意料中的结果:float在转成double的时候出现了精度的丢失问题
a = 0.0001
b = 0.100000001490116
c = 0
如果是在类型转换的时候导致的精度丢失,那我把b改为double应该可以解决这个问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | namespace FloatTest { class Program { static void Main( string [] args) { double a = 0.0001; double b = 0.1; int c = ( int )((a * 1000) / b); Console.WriteLine( "a = {0}" , a); Console.WriteLine( "b = {0}" , Convert.ToDouble(b)); Console.WriteLine( "c = {0}" , c); Console.ReadLine(); } } } |
这次却是得到我们期望的结果:
a = 0.0001
b = 0.1
c = 1
因此,在程序中,我们应该尽量的避免浮点数类型转换导致的精度丢失。
我在GCC上做了同样的实验,结果不管哪种方式得到的结果都是正确的,我只能说可能是double Convert.ToDouble(float)的实现的原因导致的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)