用于负零浮点值

Uses for negative zero floating point value?

本文关键字:用于      更新时间:2023-10-16

考虑以下c++代码:

double someZero = 0;
std::cout << 0 - someZero << 'n';   // prints 0
std::cout << -someZero << std::endl; // prints -0

问题来了:负零有什么好处,应该防御性地避免它(即使用减法而不是在变量上加上减号)?

来自维基百科:

据称IEEE 754中包含有符号零使得在一些关键问题[1]中更容易达到数值精度,特别是在计算复杂初等函数[2]时。

第一个参考文献是W. Kahan的"复杂初等函数的分支切割或无事可做的符号位",可以在这里下载。

该论文中的一个例子是1/(+0) vs 1/(-0)。在这里,0的符号产生了巨大的差异,因为第一个表达式等于+inf,第二个表达式等于-inf

另外sign Zero For:

0可以被认为是扩展实数线的一个变体,使得1/−0 =−∞和1/+0 = +∞,除零只有在±0/±0时才没有定义。

带负符号的零呼应了从下接近0的数学分析概念,即单侧极限,可以用x→0−、x→0−或x→↑0表示。符号"- 0"可以非正式地用于表示已四舍五入为零的小负数。负零的概念在统计力学和其他学科中也有一些理论应用

我只看到两个真正的用例:

  1. 你想显示一个值是负的,但非常非常小(可能是无穷小),也就是说,太小而不能表示为float或double。
  2. 您正在使用只允许负数的数学,但仍然希望显示零。在物理学、复数和数论中有一些情况下,这是有用的。

在大多数情况下,它是没有用的,应该避免使用。

你可能还想看看这个问题:是否有一个负零?和IEEE 754规范,

我正在制作一个测量应用程序,-0对于混合数字(例如分为英尺和英寸)非常有用。

假设我们有一个变量"长度",我们想把它分成"英尺"answers"英寸"。

(这是java代码,但同样的想法也适用于c++)。

feet = Math.signum(length) * Math.floor(Math.abs(length / 12));
// could also do feet = length>0 ? Math.floor(length / 12) : Math.ceil(length / 12)
inches = Math.abs(length) % 12;

如果长度在-1英尺到0英尺之间,我们希望它为英尺表示-0,这样我们就知道它是负的。

负零在处理复数时有一些用途…

在日常使用中,我们应该尽量避免使用负零。


一些关于"负零"的背景/使用/缺陷的信息链接:
  • http://en.wikipedia.org/wiki/Signed_zero
  • http://en.wikipedia.org/wiki/Floating_point Signed_zero
  • http://en.wikipedia.org/wiki/Branch_cut
  • http://connect.microsoft.com/VisualStudio/feedback/details/344366/negative-zero-behavior-between-c-and-c-code-is-different
  • http://connect.microsoft.com/VisualStudio/feedback/details/292276/in-vs2005-c-zero-reported-as-negative-zero-for-double-type
  • c++ ceil和负零