为什么PHP不为浮点比较提供Epsilon常量?

时间:2014-05-23 19:44:38

标签: php floating-point epsilon

在看到许多关于比较浮点数相等的PHP问题之后,答案是简单地选择Epsilon的任意值,然后执行if( abs($a-$b) < 0.000001 )

麻烦的是,Epsilon通常 小于人们倾向于选择的值[我的机器上的2.22e-16]并且实际上很容易计算:

$macheps = (float) 1.0;  
do {
    $macheps /= (float) 2.0;
} while( (float) (1.0 + ($macheps/2.0)) != 1.0 );
printf("Epsilon: %0.25f\n", $macheps);

C ++有std::numeric_limits<double>::epsilon(),Python有sys.float_info.epsilon,那么为什么PHP会把它留在空中呢?

2 个答案:

答案 0 :(得分:4)

我知道这是一个老问题,但从PHP 7.2开始提供。

<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="@dimen/_300sdp" android:layout_height="@dimen/_70sdp" android:layout_margin="@dimen/_10sdp" android:layout_gravity="center_horizontal"> <Button android:id="@+id/lb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/_32sdp" android:background="@drawable/left_side" android:textSize="@dimen/_20sdp" android:gravity="center" android:text="left" android:textAllCaps="false" app:layout_constraintHorizontal_chainStyle="packed" /> <android.support.v4.widget.Space android:id="@+id/marginSpacer" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toTopOf="@id/lb" app:layout_constraintLeft_toRightOf="@+id/lb" /> <TextView android:id="@+id/rtTvData" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/right_side" android:gravity="center" android:textSize="@dimen/_20sdp" android:layout_marginStart="@dimen/_70sdp" app:layout_constraintLeft_toLeftOf="@id/marginSpacer" app:layout_constraintRight_toRightOf="@id/marginSpacer" app:layout_constraintTop_toBottomOf="@+id/marginSpacer" android:text="Right" /> </android.support.constraint.ConstraintLayout> (浮动)

最小的可表示正数x,因此x + 1.0!= 1.0。从PHP 7.2.0开始提供。

请参阅http://php.net/manual/en/reserved.constants.php

答案 1 :(得分:3)

C ++的std::numeric_limits<double>::epsilon()从未打算在样式0.000001的公式中用来代替abs($a-$b) < 0.000001。例如,对于大多数C ++编译平台,fabs(x - 2.5) < std::numeric_limits<double>::epsilon()等同于x == 2.5,因为std::numeric_limits<double>::epsilon()double附近1定义的表示。

有些程序员可能需要将浮点数与某个值进行比较,但该值几乎没有理由与1附近的浮点格式的定义相关,因此这不是提供该常数的理由。语言。相反,该值应该来自需求(“尽可能小”)或推理(“浮点结果可以是真实结果的0.003,因此如果实际结果可以fabs(x - 2.5) < 0.003永远不会为假是2.5“)。