English 中文(简体)
C++转换为更精确的类型并失去准确性?
原标题:C++ cast to a more precise type and lose accuracy?

考虑两种计算方法:

  1. data in double precision
    -> apply a function with double precision temporaries
    -> return result
  2. data in double precision
    -> cast to long double
    -> apply a function with long double precision temporaries
    -> cast to double
    -> return result

与第一种解决方案相比,第二种解决方案是否会给出不太准确的结果?如果是,在什么情况下?

最佳回答

对证明:设c=0x1p-53+0x1p-64。使用double和long double(常见的Intel格式,带64位有效位)计算1+c-c-1。在double中,结果为0,这是数学上精确的答案。在long double中,结果是-0x1p-64,这是错误的(在转换为double时仍然是错误的)。

在double中,1+c加起来略高于1比1的ULP(最小精度单位)的一半,因此它产生1加上ULP。减去c会减去略多于一半的ULP,因此与结果最接近的可表示数字(双倍)是1,因此产生1。然后减去1得到0。

在long double中,1+c加上0x1p-53加上ULP的半个1。(在长双精度中,1的ULP为0x1p-63。)由于结果与两个最接近的可表示数字(在长双精度中)的距离完全相同,因此返回低位为零的数字1+0x1p-53。那么减去c的确切结果是1-0x1p-64。这是完全可表示的,因此它被返回。最后,减去1得到-0x1p-64。

问题回答

关于长双,草案说:

3.9.1基本类型

8 There are three floating point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double. The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double. The value representation of floating-point types is implementation-defined. Integral and floating types are collectively called arithmetic types. Specializations of the standard template std::numeric_limits (18.3) shall specify the maximum and minimum values of each arithmetic type for an implementation.

至于促销,这是下一个最有趣的部分:

4.6浮点推广

1 A prvalue of type float can be converted to a prvalue of type double. The value is unchanged.

2 This conversion is called floating point promotion.

请注意,没有关于doublelong double的任何说明。不过,我冒着滑倒的风险。

接下来是转换,当你从long double转换为double时,我们感兴趣的是:

4.8浮点转换

1 A prvalue of floating point type can be converted to a prvalue of another floating point type. If the source value can be exactly represented in the destination type, the result of the conversion is that exact representation. If the source value is between two adjacent destination values, the result of the conversion is an implementation-defined choice of either of those values. Otherwise, the behavior is undefined.

2 The conversions allowed as floating point promotions are excluded from the set of floating point conversions.

现在,让我们看看变窄的效果:

6。窄化转换是一种隐式转换

[...]

  • from long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly)

从所有这些标准中可以得出两个结论:

  • Combining the bit about narrowing with the bit about implementation defined conversions there may be changes in your results across platforms.
  • If your intermediate results (considering multiple such results) in long double are in a range that cannot be represented accurately by a double (high or low), these can accumulate to return a different final result which you will want to return back as a double.

至于哪个更准确,我认为这完全取决于你的应用程序。





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签