То, что возможно между 8-байтовыми целыми числами и форматом с плавающей запятой, легко объяснить, но не так легко реализовать!
Следующий абзац касается того, что представимо в 8-байтовых целых числах со знаком.
Все положительные целые числа от 1 (2 ^ 0) до 16777215 (2 ^ 24-1) точно представлены в iEEE754 с одинарной точностью (с плавающей точкой).Или, если быть точным, все числа между 2 ^ 0 и 2 ^ 24-2 ^ 0 с шагом 2 ^ 0.Следующий диапазон точно представимых натуральных чисел составляет от 2 ^ 1 до 2 ^ 25-2 ^ 1 с шагом 2 ^ 1 и т. Д. До 2 ^ 39 до 2 ^ 63-2 ^ 39 с шагом 2 ^ 39.
Беззнаковые 8-байтовые целочисленные значения могут быть выражены с точностью до 2 ^ 64-2 ^ 40 с шагом 2 ^ 40.
Здесь формат одиночного пречисона не останавливается, а распространяется на всевплоть до диапазона от 2 ^ 103 до 2 ^ 127-2 ^ 103 с шагом 2 ^ 103.
Для 4-байтовых целых (длинных) самый высокий диапазон с плавающей запятой составляет от 2 ^ 7 до 2 ^ 31-2 ^ 7 с шагом 2 ^ 7.
В архитектуре x86 наибольшим целочисленным типом, поддерживаемым набором команд с плавающей запятой, является 8-байтовое целое число со знаком.2 ^ 64-1 не могут быть загружены обычными средствами.
Это означает, что для данного приращения диапазона, выраженного как "2 ^ i, где i является целым числом> 0", все целые числа, которые заканчиваются битовой комбинацией 0x1 вверхдо 2 ^ i-1 не будет точно отображаться в пределах этого диапазона в плавающем значении. Это означает, что то, что вы называете округлением вверх, на самом деле зависит от того, в каком диапазоне вы работаете. Бесполезно пытаться округлить до 1 (2^ 0) или 16 (2 ^ 4), если гранулярность диапазона, в котором вы находитесь, составляет 2 ^ 19.
Дополнительное следствие того, что вы предлагаете сделать (округление 2 ^ 63-1 до 2 ^ 63) может привести к переполнению (длинный целочисленный формат), если вы попытаетесь выполнить следующее преобразование: longlong_int = (long long) ((float) 2 ^ 63).
Проверьте эту небольшую программу, которую я написал (на C)что должно помочь проиллюстрировать, что возможно, а что нет.
int main (void)
{
__int64 basel=1,baseh=16777215,src,dst,j;
float cnvl,cnvh,range;
int i=0;
while (i<40)
{
src=basel<<i;
cnvl=(float) src;
dst=(__int64) cnvl; /* compare dst with basel */
src=baseh<<i;
cnvh=(float) src;
dst=(__int64) cnvh; /* compare dst with baseh */
j=basel;
while (j<=baseh)
{
range=(float) j;
dst=(__int64) range;
if (j!=dst) dst/=0;
j+=basel;
}
++i;
}
return i;
}
Эта программа показывает представимые диапазоны целочисленных значений.Их перекрывают: например, 2 ^ 5 представимо во всех диапазонах с нижней границей 2 ^ b, где 1 =