C# 确定是否可以用浮点/双精度格式精确表示数字

C# 确定是否可以用浮点/双精度格式精确表示数字,c#,floating-point,C#,Floating Point,如何确定一个数字,例如1.577,是否可以用浮点或双精度格式精确表示 这意味着它是真实的1.577,而不是1.56699999994324等 编辑: 我正在寻找一个工具,在那里我可以键入一个数字,它将显示它的双/浮点表示。所以这不仅仅是一个与c有关的问题。你可以使用一个。例如,输入1.577,您会得到两个不精确的指示: 1) 选中“不精确”框 2) 它以双精度浮点形式转换为1.57699999999957367435854399888477325439453125 将其与1.25这样的数字进行对

如何确定一个数字,例如1.577,是否可以用浮点或双精度格式精确表示

这意味着它是真实的1.577,而不是1.56699999994324等

编辑: 我正在寻找一个工具,在那里我可以键入一个数字,它将显示它的双/浮点表示。所以这不仅仅是一个与c有关的问题。

你可以使用一个。例如,输入1.577,您会得到两个不精确的指示:

1) 选中“不精确”框

2) 它以双精度浮点形式转换为1.57699999999957367435854399888477325439453125

将其与1.25这样的数字进行对比,1.25打印为1.25,“不精确”框不勾选


(该转换器还可以检查单精度数字。)

嗯,IEEE-754双精度有53位精度。因此,唯一可以准确表示的数字是:

  • 有理数
  • 使用终止二进制表示
  • 表示为53位或更少
因此…为了确定给定的十进制值是否可以精确表示,以下内容就足够了:

public bool IsExactlyRepresentableAsIeee754Double( decimal value )
{
  // An IEEE 754 double has 53 bits of precision (52 bits of which are explicitly stored).
  const decimal ieee754MaxBits = 0x001FFFFFFFFFFFFF ;

  // move the decimal place right until the decimal's absolute value is integral
  decimal n = Math.Abs(value) ;
  while ( Decimal.Floor(n) != n )
  {
    n *= 10m;
  }

  bool isRepresentable = n <= ieee754MaxBits ;
  return isRepresentable ;
}
public bool IsExactlyRepresentableSiee754double(十进制值)
{
//IEEE 754 double具有53位精度(其中52位显式存储)。
常量十进制ieee754MaxBits=0x001FFFFFFFFFFFFF;
//将小数点向右移动,直到小数点的绝对值为整数
十进制n=数学绝对值(值);
而(十进制楼层(n)!=n)
{
n*=10m;
}

bool isRepresentable=n您已经有了关于如何确定检查精确表示的答案。此外,能够在不进行正式测试的情况下消除许多数字,并在看到小数点后立即检查小数点,这既可行又有用

假设数字的十进制表示形式在N位小数后终止。例如,N是3表示1.577。取小数点后的部分,将其视为整数577。如果数字可以精确表示为二进制分数,则该部分必须是5^N的整数倍。577不是125的整数倍,因此为1.577不完全可以代表


如果你有一个合理大小的数字,其十进制表示中只有几个有效数字,那么如果它通过了这个测试,它就是完全可表示的。例如,我知道没有计算机测试,1.625是完全可表示的。

你有什么格式/类型的数字?你的数字是作为字符串的吗?比如说我设置了double x=1.000000001。我需要这样的函数:IsEqual(x,“1.000000001”);“我在找一个工具”-在这种情况下,您的问题将被关闭。若要通过编程检查数字是否可以精确表示,您可以查看:编写该工具的人从未学会如何打印浮点数。@leppie:是的。可以正确打印浮点数的算法不止一种。@leppie:我不这么认为这就是转换器的重点。它的目标是显示转换后的二进制浮点数的精确值(十进制,以及其他可能的形式),而不是(通常)Burger和Dybvig给出的近似值。使用Burger和Dybvig来显示在转换为二进制时以十进制表示的一般值是如何近似的,这有点毫无意义。@leppie:只是为了回应Mark所说的,转换器的主要目的不是打印像Burger和Dybvig这样的舍入值,Steele and White或David Gay。这就是让新手陷入麻烦的原因。他们输入0.1,机器打印回0.1。他们不知道在内部,值不是0.1。这就是我编写工具的原因。这应该如何工作?似乎你的代码会说
0.1
是可表示的,这是错误的。