最近我不得不将双序列化为文本,然后将其取回.该值似乎不相等:
double d1 = 0.84551240822557006;
string s = d1.ToString("R");
double d2 = double.Parse(s);
bool s1 = d1 == d2;
// -> s1 is False
但根据MSDN:标准数字格式字符串,"R"选项应该保证往返安全.
往返("R")格式说明符用于确保转换为字符串的数值将被解析回相同的数值
为什么会这样?
程序需要读取三个坐标的值
以及另一个坐标P(x,y)并确定该点是否在由上述3点形成的三角形内.
每个人都知道,或者至少每个程序员都应该知道,使用该float类型可能会导致精确错误.但是,在某些情况下,确切的解决方案会很好,并且有些情况下使用epsilon值进行比较是不够的.无论如何,这不是重点.
我知道DecimalPython中的类型,但从未尝试过使用它.它声明"十进制数字可以准确表示",我认为这意味着一个聪明的实现,允许表示任何实数.我的第一次尝试是:
>>> from decimal import Decimal
>>> d = Decimal(1) / Decimal(3)
>>> d3 = d * Decimal(3)
>>> d3 < Decimal(1)
True
非常失望,我回到文档并继续阅读:
算术的上下文是指定精度的环境[...]
好的,所以实际上有一个精度.经典问题可以复制:
>>> dd = d * 10**20
>>> dd
Decimal('33333333333333333333.33333333')
>>> for i in range(10000):
...    dd += 1 / Decimal(10**10)
>>> dd
Decimal('33333333333333333333.33333333')
所以,我的问题是:有没有办法让Decimal类型具有无限精度?如果不是,那么比较2个十进制数的更优雅的方法是什么(例如,如果delta小于精度,则d3 <1应该返回False).
目前,当我只进行分割和乘法时,我使用的Fraction类型:
>>> from fractions import Fraction
>>> f = Fraction(1) / Fraction(3)
>>> f
Fraction(1, 3) …这个主题在StackOverflow上出现了很多次,但我相信这是一个新的看法.是的,我已经阅读了布鲁斯道森的文章和每个计算机科学家应该知道的关于浮点算术的内容和这个很好的答案.
据我了解,在一个典型的系统上,比较浮点数是否相等有四个基本问题:
a-b是"小"取决于规模a和ba-b为"小"取决于类型a和b(例如浮动,双,长双)这个答案 - 又名."Google方法" - 似乎很受欢迎.它确实处理了所有棘手的案件.并且它确实非常精确地缩放比较,检查两个值是否在彼此的固定数量的ULP内.因此,例如,非常大的数字将"几乎相等"与无穷大相比较.
然而:
我想要类似的东西,但使用标准的C++并处理长双打.如果可能的话,我指的是C++ 03,如果需要,我指的是C++ 11.
这是我的尝试.
#include <cmath>
#include <limits>
#include <algorithm>
namespace {
// Local version of frexp() that handles infinities specially.
template<typename T>
T my_frexp(const T num, int *exp)
{
    typedef std::numeric_limits<T> limits;
    // Treat +-infinity as +-(2^max_exponent).
    if (std::abs(num) > limits::max())
    {
        *exp …在算法的某个时刻,我需要将类的属性的浮点值与浮点数进行比较.所以我这样做:
if (self.scroller.currentValue <= 0.1) {
}
其中currentValue是一个浮动属性.
但是,当我具有相等性并且self.scroller.currentValue = 0.1if语句未满足且代码未执行时!我发现我可以通过将0.1转换为浮动来解决这个问题.像这样:
if (self.scroller.currentValue <= (float)0.1) {
}
这很好用.
任何人都可以向我解释为什么会这样吗?默认情况下,0.1是否定义为double?
谢谢.
看看这段代码:
#include <cmath>
#include <iostream>
using namespace std;
class Sphere
{
    double r;
public:
    double V() const { return (4/3) * 3.14 * pow(r,3); }
    bool equal(const Sphere& s) const
    {
        cout  << V() << " == " << s.V() << " : " << ( V() == s.V() );
        return ( V() == s.V() );
    }
    explicit Sphere(double rr = 1): r(rr){}
};
main()
{
    Sphere s(3);
    s.equal(s);
}
输出是84.78 == 84.78 : 0指同一方法每次都不返回相同的值,即使所有参数都是静态的?
但是如果我写的3.0不是 …
我试图比较两个相同的纬度,它是类型的Double,当我打印结果时,它被评估为false.
print("spot latitude: " + String(spot.location.latitude))
print("first object: " + String(firstSpot.location.latitude))  
print(spot.location.latitude == firstSpot.location.latitude)
输出:
spot latitude: 32.8842183049047
first object: 32.8842183049047
false
任何人都知道发生了什么?
每当我搜索"非正规数"或"非正规数"这个术语时,我只会找到如何检测它们并将它们舍入为零的方法.显然,没有人真正喜欢它们,因为与它们打交道会导致性能下降.
然而,它们在各地实施.为什么?如果它是精确的,我会说你需要一个更大的浮动,或者改变你的操作顺序,这样你就可以避免非常小的中间值.我发现很难相信这一点额外的精度真的值得宝贵的时钟周期.
有没有什么好的理由让人们仍然使用非正规数?如果没有明显的理由有非正规数字,为什么要实现它们呢?只是符合IEEE754标准吗?)
在Delphi6或Delphi 2010中,声明两个Currency类型的变量(vtemp1,vtemp2),并为它们提供0.09的值.使用ABS功能嵌入其中一个变量并将其与另一个进行比较.当编译器监视显示abs(vtemp1)和vtemp2的相同值时,您可能希望比较产生正结果.奇怪的是if语句失败了!
注意: - 只有在处理数字0.09时才会遇到此问题(尝试其他几个接近的值显示正常结果) - 将变量解释为Double而不是货币,问题就不复存在了.
查看此链接的输出(向下滚动以查看输出)以找出我要完成的任务
问题在于for第9-11行的循环
for(i=0; i<=0.9; i+=0.1){
  printf("%6.1f ",i);
}
我预计这会打印从0.0到0.9的值,但它会在打印0.8后停止,任何想法为什么?