为什么从转换为unsigned long long翻番可能会导致数据丢失? [英] Why conversion from unsigned long long to double can lead to data loss?
问题描述
当我通过编译这个微不足道的一块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.000000When 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屋!