【问题标题】:truncated integer division removal截断整数除法删除
【发布时间】:2016-02-15 10:37:03
【问题描述】:

如何在这段代码中避免截断整数除法?我的排序数组是1 1 1 1 1 1,所以 a[0] = 1 和 a[n] 应该是 1 / 2 = 0.5。

int main()
{
    long long n,w;
    scanf("%lld %lld", &n, &w);
    long long arr[2*n];
    for(long long i = 0; i < 2 * n; i++)
    {
      scanf("%lld", &arr[i]);
    }
    sort(arr,arr+2*n);

    long long a = arr[0];
    long long b = (float)(arr[n]/2); // <--- this part of code
    cout << " a is " << a << endl;
    cout << " b is " << b << endl;
    long long m = min(a,b);
    cout << " m is " << m << endl;
    long long and = min(m * n + m * 2LL * n, w);
    printf("%lld", ans);
    return 0;
}

【问题讨论】:

  • C 还是 C++?它们是不同的语言。
  • 帖子不是有效的 C 代码。
  • long long 到 float 的转换肯定会丢失大值的精度。

标签: c++ division long-long


【解决方案1】:

b 变量不能保存浮点数,因为它是整数。不仅您到float 的转换发生得太晚,而且您将结果存储在一个整数变量中。除了整数结果,你怎么能期待别的呢?

float b = ((float)arr[n])/2.f;

会产生更好的结果。

【讨论】:

    【解决方案2】:

    结果:

    arr[n] / 2
    

    是一个整数表达式,因为两个操作数都是整数。因此,它执行整数除法,并且您失去了所需的精度。之后将(整数)结果转换为float 将无济于事,因为精度只是不存在。

    要获得所需的精度,请在除法之前将两个操作数都设为floats:

    float b = (float) arr[n] / 2.f;
    

    【讨论】:

    • 肯定只需要一个浮点数吗?我经常做arr[n] / 2.0 之类的事情,以便将表达式强制转换为浮点数。 (现在我想知道没有文字后缀的默认精度是多少)
    【解决方案3】:

    如何避免在这段代码中截断整数除法?

    将值缩放 2,最后只除以 2。

    int main(void) {
        long long n,w;
        scanf("%lld %lld", &n, &w);
        long long arr[2*n];
        for(long long i = 0; i < 2 * n; i++)
        {
          scanf("%lld", &arr[i]);
        }
        sort(arr,arr+2*n);
    
        long long a2 = arr[0]*2;
        long long b2 = arr[n];
    
    
        printf("a*2 %lld\n",  a2);
        printf("b*2 %lld\n",  b2);
        long long m2 = min(a2,b2);
        printf("m*2 %lld\n",  m2);
    
        long long ans2 = min(m2 * n + m2 * 2LL * n, w*2);
        printf("ans*2 %lld\n",  ans);
        printf("ans %lld.%d\n",  ans2/2, abs(ans%2)*5);
        return 0;
    }
    

    注意:在 C 中,确保 long long min(long long a, long long b) 具有该签名。

    【讨论】:

      猜你喜欢
      • 2010-12-18
      • 2014-05-25
      • 1970-01-01
      • 2011-01-26
      • 2019-04-04
      • 2015-07-11
      • 1970-01-01
      相关资源
      最近更新 更多