【问题标题】:cast from double* to int loses precision从 double* 转换为 int 会失去精度
【发布时间】:2019-10-23 03:18:50
【问题描述】:

ddouble 类型的数据,p 是指向它的指针。当它们都分别显式地转换为 int 时,它会为指针 p 的转换给出以下错误。 : 从double* 转换为int 会丢失精度

#include<iostream>
using namespace std;
int main()
{
    int i,j;
    double d=3.5;
    double* p=&d;
    i=(int)d;
    j=(int)p;   // this line gives the error
    cout<<i<<" "<<j;
    return 0;
}

我预计会有错误 "从double*int 的转换无效。为什么不是这样?

另外,如果对指针p 这样做,为什么数据 d 的强制转换没有给出“丢失精度”错误?

【问题讨论】:

    标签: c++ casting int double


    【解决方案1】:

    你失去了精确性,这是不言自明的。

    在这种情况下,您这样做有两个原因。

    1. 整数只有 4 个字节,而 double 有 8 个字节,这意味着您不能将整个 double 放入整数。 (实际上它是由实现定义的)
    2. double 有十进制数,整数没有,所以整数根本不能保存十进制数的信息。

    行错误的原因是因为您试图将指针转换为整数,这是不可能的,您的意思是j = (int)*p;

    您的代码中有几个不好的做法。

    1. 使用命名空间标准; Why is "using namespace std;" considered bad practice?

    https://isocpp.org/wiki/faq/coding-standards#using-namespace-std

    How to use an iterator?(导致问题的例子)

    Confusion about pointers and references in C++(另一个导致问题的例子;使用 std::swap;也会导致同样的问题)

    1. C 风格转换 这是(type),在你的情况下特别是(int) 在 C++ 中应该使用 2 个主要类型转换,static_cast 和 reinterpret_cast。 (还有另外 2 种类型,const_cast 和 dynamic_cast,但在这种情况下这些是无关紧要的,而且 const_cast 几乎不应该使用)

    两者都将模板参数作为结果类型。

    在这种情况下,您可能可以i = static_cast&lt;int&gt;(d);

    对于第二个转换,j =,您应该(实际上您不应该将指针转换为不同的类型)

    j = *reinterpret_cast&lt;int*&gt;(p);

    当然,将双精度数转换为整数并不好,但这应该可以解决您的编译器错误。

    【讨论】:

    • *reinterpret_cast&lt;int*&gt;(p) 是 UB,不应使用。
    • 同意,不应该使用,同意。他根本不应该将双精度数转换为整数。我意识到这是未定义的行为,我只是想举一个关于 reinterpret_cast 的例子,在这种情况下他最好做static_cast&lt;int&gt;(*p)
    • 可能我遗漏了什么,但*reinterpret_cast&lt;int*&gt;(p)static_cast&lt;int&gt;(*p) 做的事情完全不同。
    • 再次正确,我想举一个关于 reinterpret_cast 的例子,因为我刚刚给出了 C++ 中的两种主要类型。
    • “你应该” 然后“同意,不应该使用,同意”
    【解决方案2】:

    int 不保证能够保存指针的值。在您的情况下,我相信 intptr_t 会起作用。

    【讨论】:

      【解决方案3】:

      我预计错误是“从 'double*' 到的无效转换 'int'"。为什么不是这样?

      我认为这只是一种处理此错误的依赖于编译器的方式。在铿锵声中,我得到了类似的东西,也许信息更丰富:

      error: cast from pointer to smaller type 'int' loses information
      

      另外,为什么数据 d 的演员表没有给出“丢失精度”错误 如果它对指针 p 这样做?

      从 float 或 double 到 int 的转换属于标准转换,不会出错且有时很有用。这不应该抛出错误,更多的是here

      浮点类型的纯右值可以是 转换为任何整数类型的纯右值。小数部分是 截断,即小数部分被丢弃。如果值 不适合目标类型,行为未定义(甚至 当目标类型为无符号时,模运算不会 申请)。如果目标类型是 bool,这是一个布尔转换 (见下文)。

      整数或无范围枚举类型的纯右值可以是 转换为任何浮点类型的纯右值。如果值不能 被正确表示,它是实现定义是否 最接近的较高或最接近的较低可表示值将是 已选择,但如果支持 IEEE 算法,则舍入默认值 到最近。如果该值不适合目标类型,则 行为未定义。如果源类型为 bool,则值为 false 转换为零,值 true 转换为一。

      【讨论】:

        猜你喜欢
        • 2022-12-31
        • 2010-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多