代码之家  ›  专栏  ›  技术社区  ›  MichaelE

值乘以-1的数学错误?

  •  -8
  • MichaelE  · 技术社区  · 6 年前

    给定以下基本代码:

    double x = 3;
    return x *-1;
    

    1.844674e+19 (受产量限制)或一个疯狂的大数字。简单地做 return -x; 也不起作用。

    更改代码:

    double x = 3;
    return x *-1.0;
    

    返回正确的输出。 这似乎是一些整数对双或布尔值的问题。 我知道,不显式地将整数划分为double就可以给出0而不是一个分数,但我从未见过它会导致乘法或加法的问题。

    有没有人能告诉我发生了什么事,或者指出对这种行为的解释以及如何处理?

    功能:

    // [[Rcpp::export]]
    double test1(double data)
    {
      std::vector<double> testArray(data);
      return (testArray.size()*-1);
    }
    

    从R运行:

    test1(4)
    

    结果:

    [1] 1.844674e+19
    

    编辑2:我想我明白了。 托比是对的,它是一个不带符号的值,不能转换为double。 在我的原始样本中:

    // [[Rcpp::export]]
    double test1(double data)
    {
      std::vector<double> testArray(data);
      double arraySize = testArray.size();
      return (arraySize*-1);
    }
    

    首先将其转换为double,然后乘以-1.0也可以很好地工作。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Toby Speight    6 年前

    尽管您认为您的代码与此类似:

    #include <iostream>
    
    double f()
    {
        double x = 3;
        return x * -1;
    }
    
    int main()
    {
        std::cout << f() << std::endl;
    }
    

    x 从向量的结果 size() std::size_t :

    #include <cstdint>
    #include <iostream>
    
    double f()
    {
        std::size_t x = 3;
        return x * -1;
    }
    
    int main()
    {
        std::cout << f() << std::endl;
    }
    

    标准:尺寸 乘以 int . 当一个参数被签名,一个未签名时的提升规则表明(来源: CppReference )

    如果无符号操作数的转换秩大于或等于有符号操作数的转换秩,则将有符号操作数转换为无符号操作数的类型。

    通常比 ,所以我们现在将3乘以 (std::size_t)-1 -大量的。当我们 return ,此大数字转换为 double f() .

    这个问题可以通过以下几种方式避免:

    • 存储的结果 大小()
    • 转换结果 大小() static_cast<> 乘法时为有符号或浮点类型。
    • -1.0 )-这将导致另一个参数提升为浮点。