c# float和double的“坑”

定义一个float类型的变量=0.7,结果在IL中却是0.69999999。

乘以10之后,获取整数值。得到的却是6。通过查看IL,竟然被转换成double类型再转换。就变成6了。

Demo:

IL:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代码大小       93 (0x5d)
  .maxstack  2
  //定义变量
  .locals init ([0] float32 val,
           [1] int32 i)
  IL_0000:  nop
  IL_0001:  ldc.r4     0.69999999
  //将0.69999999赋值给第0个变量。明明定义的是0.7
  IL_0006:  stloc.0
  IL_0007:  ldc.i4.s   10
  /将10赋值给第一个变量
  IL_0009:  stloc.1
  //double类型的0.7
  IL_000a:  ldc.r8     0.69999999999999996
  IL_0013:  ldloc.1
  IL_0014:  conv.r8
  IL_0015:  mul
  IL_0016:  call       float64 [mscorlib]System.Math::Floor(float64)
  IL_001b:  call       void [mscorlib]System.Console::WriteLine(float64)
  IL_0020:  nop
  IL_0021:  ldloc.0
  IL_0022:  call       void [mscorlib]System.Console::WriteLine(float32)
  IL_0027:  nop
  //从堆栈中加载出val
  IL_0028:  ldloc.0
  //从堆栈中加载出i
  IL_0029:  ldloc.1
  //将i转换为float类型
  IL_002a:  conv.r4
  //val*i
  IL_002b:  mul
  //将乘法运算之后的结果转换为double类型
  IL_002c:  conv.r8
  //调用Math.Floor对运算后的结果处理
  IL_002d:  call       float64 [mscorlib]System.Math::Floor(float64)
  IL_0032:  call       void [mscorlib]System.Console::WriteLine(float64)
  IL_0037:  nop
  IL_0038:  ldloc.0
  IL_0039:  conv.r8
  IL_003a:  call       void [mscorlib]System.Console::WriteLine(float64)
  IL_003f:  nop
  IL_0040:  ldloc.0
  IL_0041:  ldloc.1
  IL_0042:  conv.r4
  IL_0043:  mul
  IL_0044:  conv.r8
  IL_0045:  call       void [mscorlib]System.Console::WriteLine(float64)
  IL_004a:  nop
  IL_004b:  ldloc.0
  IL_004c:  conv.r8
  IL_004d:  ldloc.1
  IL_004e:  conv.r8
  IL_004f:  mul
  IL_0050:  call       void [mscorlib]System.Console::WriteLine(float64)
  IL_0055:  nop
  IL_0056:  call       string [mscorlib]System.Console::ReadLine()
  IL_005b:  pop
  IL_005c:  ret
} // end of method Program::Main

c# float和double的“坑”

时间: 2024-11-03 13:18:30

c# float和double的“坑”的相关文章

Java中的简单浮点数类型float和double不能够进行精确运算

在java中,简单的浮点类型float和double是不能够进行运算.我们先看下面的两个程序代码: 代码一: import java.util.Scanner; class Circle { double radius; static final double PI=3.14; public Circle(){this.radius=0;} public Circle(double r){this.radius=r;} public double getArea(){return PI*this

Java 浮点数 float或double类型的表示范围和精度

隐约记得,浮点数判断大小好像有陷阱,因为底层的二进制数不能精确表示所有的小数.有时候会产生让人觉得莫名其妙的事情. 如在java中, 0.99999999f==1f //true 0.9f==1f //false 要明白这些,首先要搞清楚float和double在内存结构 1.内存结构 float和double的范围是由指数的位数来决定的. float的指数位有8位,而double的指数位有11位,分布如下: float: 1bit(符号位) 8bits(指数位) 23bits(尾数位) dou

Java中浮点型数据Float和Double进行精确计算的问题

一.浮点计算中发生精度丢失  大概很多有编程经验的朋友都对这个问题不陌生了:无论你使用的是什么编程语言,在使用浮点型数据进行精确计算时,你都有可能遇到计算结果出错的情况.来看下面的例子. // 这是一个利用浮点型数据进行精确计算时结果出错的例子,使用Java编写,有所省略. double a = (1.2 - 0.4) / 0.1;System.out.println(a); 如果你认为这个程序的输出结果是“8”的话,那你就错了.实际上,程序的输出结果是“7.999999999999999”.好

float与double的范围和精度

1 范围 float和double的范围是由指数的位数来决定的. float的指数位有8位,而double的指数位有11位,分布如下: float: 1bit(符号位) 8bits(指数位) 23bits(尾数位) double: 1bit(符号位) 11bits(指数位) 52bits(尾数位) 于是,float的指数范围为-127~+128,而double的指数范围为-1023~+1024,并且指数位是按补码的形式来划分的.其中负指数决定了浮点数所能表达的绝对值最小的非零数:而正指数决定了浮

java控制float和double的精度

在做读取Excel表格数据时,碰到有小数点的数字,用double和float来求和时会多出好多位小数,看起来总觉得怪怪的,怎样控制它的长度呢? DecimalFormat df = new DecimalFormat("########.0"); //四舍五入 value = Double.parseDouble(df.format(value)); 我这里是控制一位小数,如果要求两位,就写成########.00 java控制float和double的精度,布布扣,bubuko.co

金融、支付行业的开发者不得不知道的float、double计算误差问题

在大多数行业涉及到浮点数的计算的场景比较少,但是在金融.支付行业就比较多了,而且在这两个行业一个小小的错误 可能将会给公司带来极大的损失. 以前我们公司就出现了这样的一个问题,当时使用的是double类型进行计算,导致计算出来的结果与实际的结果少了几十 元钱.虽然数额不大,但是引起产品.技术的重视.通过查阅相关资料,终于知道了是因为float.double在对含有小数的数值进行 计算过程中的舍入产生了误差. 在浮点运算中,浮点运算很少是精确的.虽然一些数字(譬如 0.5 )可以精确地表示为二进制

java中int,float,long,double取值范围,内存泄露

java中int,float,long,double取值范围是多少? 写道 public class TestOutOfBound { public static void main(String[] args) { System.out.println(Integer.MAX_VALUE-(-Integer.MAX_VALUE)); //内存溢出System.out.println(Integer.MAX_VALUE); //2的31次方-1,10个数位,正的20亿左右,用在钱上面不一定够Sy

C语言中关于float、double、long double精度及数值范围理解

IEEE754浮点数的表示方法.C语言里对float类型数据的表示范围为-3.4*10^38-+3.4*10^38.double为-1.7*10^-308~1.7*10^308,long double为-1.2*10^-4932~1.2*10^4932. 类型 比特(位)数 有效数字 数值范围 float 32 6~7 -3.4*10^38-+3.4*10^38 double 64 15~16 -1.7*10^-308~1.7*10^308 long double 128/ 18~19 -1.2

Java随笔:float、double精确性

通常会用float.double进行货币的计算. 下面这个计算会输出什么? System.out.println(2.00 - 1.10); 开始以为会是0.90,实际结果是:0.8999999999999999 原因在于,不是所有的小数都可以用二进制浮点精确地表示. 如何改造呢? 用int.long进行计算,再转换为浮点数. 用BigDecimal进行计算. System.out.println(new BigDecimal("2.00").subtract(new BigDecim