为什么从转换为unsigned long long翻番可能会导致数据丢失? [英] Why conversion from unsigned long long to double can lead to data loss?

查看:534
本文介绍了为什么从转换为unsigned long long翻番可能会导致数据丢失?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我通过编译这个微不足道的一块code的微软2008年VC:

 双maxDistance(无符号长长*一,无符号长长* B,INT N)
{
    双MAXD = 0,currentD = 0;
    的for(int i = 0; I< N ++ I)
    {
        currentD = B [Ⅰ] - 一个由[i];
        如果(currentD> MAXD)
        {
            MAXD = currentD;
        }
    }
    返回MAXD;
}

编译器给我:


  

警告C4244指出:从数据的无符号长长'到'双',可能损失的转换。上线


  currentD = B [I]  - 一个[I]

我知道,这是更好地莫名其妙地改写code,我使用双占的差异可能带来的负面价值,但我只是好奇,为什么在世界转换为unsigned long long翻番可导致数据丢失,如果无符号长长的范围是从0到18,446,744,073,709,551,615和DOUBLE
 +/- 1.7E +/- 308?


解决方案

这是IEEE双precision浮点数具有尾数53位。这意味着,(大多数)的整数大于2 53 不能被精确地存储在双

范例程序(这是GCC,使用%I64u 的MSVC):

 的#include<&stdio.h中GT;诠释主(){
    无符号长长ULL;    ULL =(1ULL<< 53) - 1;
    的printf(%LLU%F \\ N,ULL,(双)ULL);    ULL =(1ULL<< 53)+ 1;
    的printf(%LLU%F \\ N,ULL,(双)ULL);    返回0;
}

输出:

  9007199254740991 9007199254740991.000000
9007199254740993 9007199254740992.000000

When I compile this trivial piece of code via Microsoft's VC 2008:

double maxDistance(unsigned long long* a, unsigned long long* b, int n)
{
    double maxD = 0, currentD = 0;
    for(int i = 0; i < n; ++i)
    {
        currentD = b[i] - a[i];
        if(currentD > maxD)
        {
            maxD = currentD;
        }
    }
    return maxD;
}

The compiler gives me:

warning C4244 stating: conversion from 'unsigned long long' to 'double', possible loss of data. On the line

currentD = b[i] - a[i]

I know that it's better to rewrite the code somehow, I use double to account for possible negative values of the difference, but I'm just curious, why in the world conversion from unsigned long long to double can lead to data loss if unsigned long long's range is from 0 to 18,446,744,073,709,551,615 and double is +/- 1.7E +/- 308 ?

解决方案

An IEEE double-precision floating point number has 53 bits of mantissa. This means that (most) integers greater than 253 can't be stored exactly in a double.

Example program (this is for GCC, use %I64u for MSVC):

#include <stdio.h>

int main() {
    unsigned long long ull;

    ull = (1ULL << 53) - 1;
    printf("%llu %f\n", ull, (double)ull);

    ull = (1ULL << 53) + 1;
    printf("%llu %f\n", ull, (double)ull);

    return 0;
}

Output:

9007199254740991 9007199254740991.000000
9007199254740993 9007199254740992.000000

这篇关于为什么从转换为unsigned long long翻番可能会导致数据丢失?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆