日期:2014-05-18  浏览次数:21073 次

高手速来接分, 1.575不进位 1.475进位, 1.275又不进位
据我所知四舍五入一般有两种规则
1. 四舍五入, 就是我们小学学的 不多说

2. 四舍六入五凑偶  
  2.1 当计算位<>5 : 四舍六入
  2.2 当计算位=5 :  
  是否为末位?
  是: 前一位为偶数? 舍去 否则 进位
  否: 进位


请解释以下现象

SQL code


DECLARE @f1 FLOAT
SET @f1 = 1.575
SELECT  @f1 ,
        ROUND(@f1, 2)

DECLARE @f2 FLOAT
SET @f2 = 1.475
SELECT  @f2 ,
        ROUND(@f2, 2)

DECLARE @f3 FLOAT
SET @f3 = 1.275
SELECT  @f3 ,
        ROUND(@f3, 2)




---------------------- ----------------------
1.575 1.57

(1 行受影响)

   
---------------------- ----------------------
1.475 1.48

(1 行受影响)

   
---------------------- ----------------------
1.275 1.27

(1 行受影响)

------解决方案--------------------
float类型本来都不精确,所以每次显示有差异
------解决方案--------------------
额 没想过这个。
------解决方案--------------------
浮点数的存储很特殊,大部分不能用精确值来判断,至于哪些浮点数可以是精确值,下面摘一段文字,地址
http://www.cnblogs.com/egust/articles/1793660.html

浮点数的储存方式则是符合IEEE 754标准的,按照这个标准,无法不通过FPU直接利用指针在不同精度的浮点类型之间转换。关于浮点数的储存方式,本文只作简单的原理性的介绍;有兴趣的话,可以参考wikipedia关于IEEE 754的介绍(英文,中文),去了解更详细的内容。
介绍浮点数类型也是为了说明一个在许多教材中、或是文章中语焉不详的内容:为什么浮点数无法精确表示一些实数,为什么运算后会存在误差,以及在哪些情况下是没有误差的。首先,浮点数由三个部分组成,能表示一定范围内的一个实数,包括0、无穷与NaN(Not a Number)。
浮点数要能表示正数与负数,所以需要占用一位(Bit)来记录符号,也就是IEEE 754浮点数类型的第一部分:符号位。从字面上理解,浮点数要有一个浮动的小数点,也就是指定该实数的指数——第二部分可以理解成主要起这个作用。要注意的是,在计算机中的“指数”的底数,并不是我们日常10进制所使用的10,而是2。换句话说,我们平时的0.125可以写成1.25*10^-1,而在计算机中,要把它变成2进制,也就是1*2^-3。第三部分则是小数位,用它加上1再乘以指数部分,得到的结果就是我们要表示的数。
那么接下来的问题是,浮点数类型能精确表示哪些数?先来考虑一个问题,二进制浮点数如何表示十进制中的0.1,也就是1*10-1?在浮点数中,指数位是2^N,所以0.1只能用2^E1+2^E2+...+2^En相加得出。这个问题可以先放一下,考虑一下2^N(N<0)都是哪些数:2^-1=0.5,2^-2=0.25,2^-3=0.125,2^-4=0.0625……因为10=2*5,所以10^N=2^N * 5^N,2^N=10^N / 5^N=10^N * 5^-N。所以,当N<0时,2^-x=5^x*10^-x,也就是说,二进制每多一位小数,十进制就会增加一位,并且新增的最右边的位是5。因此,十进制里的0.1无法用二进制的小数精确的表示,在二进制里,它是个无限小数。所以,对于浮点数准确性的结论就是:
只要换算为2进制后,是二进制的有理数,并且在数据精度范围之内,那么这个实数就是能用浮点数精确表示的。
------解决方案--------------------
float 和 real
用于表示浮点数字数据的近似数字数据类型。浮点数据为近似值;并非数据类型范围内的所有数据都能精确地表示。
float 和 real一般用在对数据没有严格精确性要求的情况, 例如做服务器性能监控, 对于性能指标的值一般用 float, 因为这类值并不需要很精确, 而且有的性能指标的值非常大. 
要达到精确性,一般都用有精确性的 decimal/numeric,
------解决方案--------------------
DECLARE @f1 FLOAT
SET @f1 = 1.575
SELECT @f1-- ,ROUND(@f1, 2)

DECLARE @f2 FLOAT
SET @f2 = 1.475
SELECT @f2-- , ROUND(@f2, 2)

DECLARE @f3 FLOAT
SET @f3 = 1.275
SELECT @f3 --,ROUND(@f3, 2)

/*
----------------------------------------------------- 
1.575

(所影响的行数为 1 行)


----------------------------------------------------- 
1.4750000000000001

(所影响的行数为 1 行)


----------------------------------------------------- 
1.2749999999999999

(所影响的行数为 1 行)


------解决方案--------------------
嗯,与精度有关。
------解决方案--------------------
用decimal试了没?
------解决方案--------------------
很正常 精度问题 不是真实 是 1.575 后面还有N位的小数
------解决方案--------------------
不要用Round,这个不是很精确,你可以用这个方法String.Format("{0:F}", yxing_time)