Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如果在IEEE 754中可以用二进制格式表示,硬码浮点是否精确?_C++_C_Floating Point_Precision_Floating Accuracy - Fatal编程技术网

C++ 如果在IEEE 754中可以用二进制格式表示,硬码浮点是否精确?

C++ 如果在IEEE 754中可以用二进制格式表示,硬码浮点是否精确?,c++,c,floating-point,precision,floating-accuracy,C++,C,Floating Point,Precision,Floating Accuracy,例如,0,0.5,0.15625,1,2,3。。。是从IEEE 754转换而来的值。他们的硬代码版本精确吗 例如: float a=0.5; float b=0.25; float c=0.125; 是 总是返回真值吗?其他例子: float a=0.5; float b=0.25; float c=0.125; a*b是否始终等于0.125,a*b==c是否始终为真?还有一个例子: int a=123; float b=0.5; a*b总是61.5吗?或者一般来说,整数乘以IEEE 75

例如,0,0.5,0.15625,1,2,3。。。是从IEEE 754转换而来的值。他们的硬代码版本精确吗

例如:

float a=0.5;
float b=0.25;
float c=0.125;

总是返回真值吗?其他例子:

float a=0.5;
float b=0.25;
float c=0.125;
a*b是否始终等于0.125,a*b==c是否始终为真?还有一个例子:

int a=123;
float b=0.5;
a*b总是61.5吗?或者一般来说,整数乘以IEEE 754二进制浮点是否精确


或者一个更一般的问题:如果值是硬代码,并且值和结果都可以用IEEE 754中的二进制格式表示(例如:0.5-0.125),那么值是否精确?

原则上,这应该是可能的。如果你把自己限制在这类具有有限二次幂表示的数字上


但这很危险:如果有人拿走了你的代码,出于任何原因将你的
0.5
更改为
0.4
,或将你的
.0625
更改为
.065
,该怎么办?那么你的代码就坏了。不,即使是过多的评论也无济于事——总有人会忽略它们。

浮点数没有固有的模糊性。只是有些,但不是全部,实数不能精确表示

与固定宽度的十进制表示法相比,比如说三位数。整数1可以用1.00表示,1/10可以用0.10表示,但1/3只能用0.33近似

如果我们改用二进制数字,整数1将表示为1.00(二进制数字),1/2表示为0.10,1/4表示为0.01,但1/3只能(再次)近似

不过,有一些事情需要记住:

  • 它和十进制数字不一样。1/10可以是 使用十进制数字精确写入0.1,但不使用二进制 数字,无论你使用多少(短于无限)
  • 在实践中,很难跟踪哪些数字可以是
    代表,但不能。0.5可以,但0.4不能。所以当你需要的时候 准确的数字,比如(经常)在用钱的时候,你不应该这样做 使用浮点数
  • 根据一些消息来源,一些处理器会做一些奇怪的事情 在对数字执行浮点计算时在内部执行 这无法准确表示,导致结果在某种程度上有所不同 这实际上是不可预测的
(我的观点是,说是的,浮点数本质上是模糊的,这实际上是一个合理的第一近似值,因此除非您确信您的特定应用程序能够处理这个问题,否则请远离它们。)


要了解更多你可能需要或想要的细节,请阅读著名的。另外,这个更容易访问的网站:。

不,但正如托马斯·帕德隆·麦卡锡所说,有些数字可以用二进制精确表示,但并非所有数字都可以


这是我向与我一起工作的非开发人员解释的方式(比如Mahmut Ali,我也在处理一个非常旧的财务包):想象一下,有一个非常大的蛋糕,切成256片。现在你可以给一个人整个蛋糕,两个人一半的蛋糕,但是一旦你决定把蛋糕分成三份,你就不能再分了——要么是85份,要么是86份——你不能再分蛋糕了。浮点也是如此。在某些表示法中只能得到精确的数字-某些数字只能是近似值。

C++不需要二进制浮点表示法。内置整数需要有二进制表示,通常是两个整数的补码,但也支持一个整数的补码、符号和大小。但浮点可以是十进制

这就引出了一个问题:C++浮点数是否可以有一个基数不为2的基数,如2和10。是否允许使用其他半径?我不知道,上次我试着检查,我失败了

但是,假设基数必须是2或10,那么所有示例都涉及2的幂,因此可以精确表示

这意味着你的大多数问题的唯一答案是“是”。例外情况是“整数乘以IEEE 754二进制浮点[exact]”的问题。如果结果超过了可用的精度,那么它就不可能是精确的,但在其他情况下是精确的

有关浮点表示和一般属性的背景信息,请参见经典


如果一个值可以用32位或64位IEEE 754精确表示,那么这并不意味着它可以用其他浮点表示法精确表示。这是因为不同的32位表示和不同的64位表示使用不同的位数来保存尾数,并且具有不同的指数范围。因此,一个可以用一种方式精确表示的数字,可能超出其他表示的精度或范围


您可以使用
std::numeric\u limits::is_iec559
(例如
T
is
double
)检查您的实现是否声称与IEEE 754兼容。但是,当打开浮点优化时,至少g++编译器(1)错误地声称是IEEE 754,而没有根据该标准正确处理NaN值等。实际上,
is_iec559
只告诉您数字表示是否为ieee754,而不告诉您语义是否一致


(1) 本质上,gcc和g++没有为不同的语义提供不同的类型,而是尝试通过编译器选项来适应不同的语义。并且单独编译程序的部分,这不能符合C++标准。

不。不,不,不,不,是的,浮点不是给出近似答案的模糊的东西。浮点数的问题涉及十进制数的表示和精度问题。实际操作本身没有任何“模糊”之处。(不过要确保你做得对,无论如何我都会非常谨慎,因为代码是t