C# 浮点数强制转换为整数,两种写法结果不一样

问题描述

floata=70.075f;intbb=(int)(a*1000);floatc=a*1000;intcc=(int)c;上面的代码按理说得到的cc和bb应该一样,但实际上bb的结果为70074,cc结果是70075。很疑惑这两种写法上有什么区别,为什么会导致这样的问题?请大神分析一下。

解决方案

解决方案二:
都75啊楼主你电脑坏了吧
解决方案三:
framework4.0刚刚测试,结果都是70075
解决方案四:
引用1楼shingoscar的回复:

都75啊楼主你电脑坏了吧

解决方案五:
我的测试结果也相同,你看下是在什么位置取值不同。
解决方案六:
楼主电脑坏了,才三个小数位,明显在精度范围内
解决方案七:
vs2005,用的是netframe2.0.是不是版本不一样导致的。另外,如果a的整数部分改为63及以下就没问题。
解决方案八:
把a换成64.075在vs2005net2.0;vs2008net3.5;vs2010net4.0下都测试了一下,结果bb和cc都是74.下图是vs2010下的监视结果。
解决方案九:
{floata=70.075f;intbb=(int)(a*1000);}{floata=70.075f;floatc=a*1000;doublex=a*1000;intcc=(int)c;}

开了一个项目试了一下,确实是这样的,调试的时候不要优化代码。问题出现在floatc=a*1000;

,这个赋值会把堆栈中的运算结果值存入变量。在这个过程中,实际的值应该是x=70074.996948242188,而因为精度问题,存入c的值是c=70075.0。这也就是我们一直避免使用float类型的原因,因为精度实在是太低了。
解决方案十:
引用7楼headgo的回复:

把a换成64.075在vs2005net2.0;vs2008net3.5;vs2010net4.0下都测试了一下,结果bb和cc都是74.

结果一样说明没问题啊
解决方案十一:
奇怪的是为何两种写法有时结果还不一样,分开写有时还能得到想要的结果。
解决方案十二:
在实际编码中别写这种靠谱的代码不就完了
解决方案十三:
引用楼主headgo的回复:

floata=70.075f;intbb=(int)(a*1000);floatc=a*1000;intcc=(int)c;上面的代码按理说得到的cc和bb应该一样,但实际上bb的结果为70074,cc结果是70075。很疑惑这两种写法上有什么区别,为什么会导致这样的问题?请大神分析一下。

可能你需要贴出你的CPU的型号,以及操作系统版本号了。单精度浮点数只有7位(十进制)左右的精度,如果你将其乘以1000,那么误差也就扩大1000倍。然后你又把float直接截断为int32数字。有你这样粗放的算法,那么这种精度损失,是很正常的(最终你在int32的值上只看到4为有效数字了)。.net在不同系统版本下、不同CPU下,编译出来的代码是不同的。而不同CPU对于指令的处理肯定也是不完全相同的。即使是.net2.0framework,你用11、12年前的与2015年是随现在的软件包而发布的.net2.0,相信它的Jit编译出的代码也是有差异的。相信最近这些年的.net在保证运算效率的基础上,也能稍微提高一些精度。电脑计算的误差在所难免。所以哪怕是很简单的四则运算的数学计算,只要是反复进行复杂迭代计算(例如解三角矩阵的逆矩阵算法),数学家也要调整传统的算法,选择一种累计误差不会扩大的算法去重写。
解决方案十四:
在实际的程序设计中,可能要考虑的因素包括:原始数据的精度,是否应该使用double而不是float,是否可以随便截断小数部分而转换为int32,是否应该先进行后边的计算处理、最后才*1000(而不是先*1000),等等。用电脑搞数学计算的人在学校里学过计算精度问题。这是相关的任何一种数值计算方面的课程的教科书,在一开始就会讲到的。
解决方案十五:
引用5楼starfd的回复:

楼主电脑坏了,才三个小数位,明显在精度范围内

中毒了可能会出现这种问题。
解决方案:
引用12楼sp1234的回复:

Quote: 引用楼主headgo的回复:
floata=70.075f;intbb=(int)(a*1000);floatc=a*1000;intcc=(int)c;上面的代码按理说得到的cc和bb应该一样,但实际上bb的结果为70074,cc结果是70075。很疑惑这两种写法上有什么区别,为什么会导致这样的问题?请大神分析一下。

可能你需要贴出你的CPU的型号,以及操作系统版本号了。单精度浮点数只有7位(十进制)左右的精度,如果你将其乘以1000,那么误差也就扩大1000倍。然后你又把float直接截断为int32数字。有你这样粗放的算法,那么这种精度损失,是很正常的(最终你在int32的值上只看到4为有效数字了)。.net在不同系统版本下、不同CPU下,编译出来的代码是不同的。而不同CPU对于指令的处理肯定也是不完全相同的。即使是.net2.0framework,你用11、12年前的与2015年是随现在的软件包而发布的.net2.0,相信它的Jit编译出的代码也是有差异的。相信最近这些年的.net在保证运算效率的基础上,也能稍微提高一些精度。电脑计算的误差在所难免。所以哪怕是很简单的四则运算的数学计算,只要是反复进行复杂迭代计算(例如解三角矩阵的逆矩阵算法),数学家也要调整传统的算法,选择一种累计误差不会扩大的算法去重写。

跟CPU和系统都有关系,不能一概而论。如果是64位的操作系统应该不会出问题。

时间: 2024-12-30 11:48:16

C# 浮点数强制转换为整数,两种写法结果不一样的相关文章

Java范型的两种写法

1.原始的DAO层的类: package com.test; public class UserDao { public void add(User user){ //.保存实体的代码 } public User get(int id) { //.查询实体的代码 return null; } } 其中,User类代码比较简单,如下: package com.test; public class User { private int id; private String name; public

select-link中这样两种写法有什么区别?

问题描述 link中这样两种写法有什么区别? var query = from x in table select x; foreach (var item in x) { ... } foreach (var item in table) { ... } 解决方案 两种写法一样,而且性能也一样

状态机的两种写法

有限状态机FSM思想广泛应用于硬件控制电路设计,也是软件上常用的一种处理方法(软 件上称为FMM--有限消息机).它把复杂的控制逻辑分解成有限个稳定状态,在每个状态 上判断事件,变连续处理为离散数字处理,符合计算机的工作特点.同时,因为有限状 态机具有有限个状态,所以可以在实际的工程上实现.但这并不意味着其只能进行有限 次的处理,相反,有限状态机是闭环系统,有限无穷,可以用有限的状态,处理无穷的 事务.     有限状态机的工作原理如图1所示,发生事件(event)后,根据当前状态(cur_st

位图-下面两种写法的区别,为什么第一种会报错?

问题描述 下面两种写法的区别,为什么第一种会报错? 第一种 BitmapFactory.decodeStream(conn.getInputStream()); 第二种 InputStream is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is); 解决方案 没有看出有什么不同,InputStream is = conn.getInputStream(); bitmap = BitmapFactory.decode

ios-下面两种写法的区别是什么

问题描述 下面两种写法的区别是什么 @interface XXX () @property (strong nonatomic) UITableView *tableView;@end@implementation XXX - (void)viewDidLoad { self.tableView = [[UITableView alloc]initWithFrame:self.view.bounds]; //vs 这两种写法的区别是什么? 有什么好处? UITableView *tbView =

java-这两种写法有什么差别???请大家帮忙看一看

问题描述 这两种写法有什么差别???请大家帮忙看一看 public void getBenjin() { if (null != benjin.getText()) { benjinD = Double.parseDouble(benjin.getText().toString()); } } public void getLilv() { if (null != lilv.getText()) { lilvD = Double.parseDouble(lilv.getText().toStri

link以下两种写法结果一样,有什么区别?

问题描述 link以下两种写法结果一样,有什么区别? 写法1: scores.GroupBy(x=>x.StuID).OrderBy(x =>x.Sum()).ThenBy(x => x.Key) 写法2: scores.GroupBy(x=>x.StuID).OrderBy(x =>x.Key).OrderBy(x=>x.Sum()) 解决方案 写法2不推荐,理论上这个结果和写法1一样,但是基于这样一个假设,那就是OrderBy执行的是稳定的排序. 所谓稳定的排序,就

ios-(IOS)这两种写法有什么区别???

问题描述 (IOS)这两种写法有什么区别??? 两种写法有一种运行后加载不了数据...第一种:-(NSArray *)messageFrames{ if (_messageFrames == nil) { NSArray *messages = [Message messagesList]; NSMutableArray *temArray =[NSMutableArray array]; for (Message *msg in messages) { MessageFrame *msgfra

ThinkPHP中Widget扩展的两种写法及调用方法详解

本文实例讲述了ThinkPHP中Widget扩展的两种写法及调用方法.分享给大家供大家参考,具体如下: Widget扩展一般用于页面组件的扩展,在页面根据需要输出不同的内容,下面介绍一下ThinkPHP中Widget的两种写法及调用 写法一: ArticlWidget.class.php文件: class ArticleWidget extends Widget { /** * * @param array $data * @return type * 调用方法:{:W('ArticleList