2015-09-01 2 views
4

При использовании представления с плавающей запятой IEEE 754 (double типа в C++) числа, которые очень близки к (представимым) целым числам, округлены до их ближайшего целого и представлены точно. Это правда?
Точно как близко число должно быть до ближайшего представляемого целого числа до округления?
Постоянно ли это расстояние?
Например, учитывая, что 1 можно представить точно, что является наибольшим double меньше 1?Плавающая точка IEEE 754, что является наибольшим числом <1?

ответ

6

При использовании стандарта IEEE 754 представления с плавающей запятой (тип double в C++), цифры, которые очень близки к (представимых) целые числа округлены до ближайшего целого их и точно представлены.

Это зависит от того, является ли число ближе к целому числу, чем к другим представляемым значениям. 0.99999999999999994 is not equal to 1, but 0.99999999999999995 is.

Постоянное ли это расстояние?

Нет, оно становится меньше при больших величинах - в частности, с большими показателями в представлении. Более крупные экспоненты предполагают, что мантисса будет охватывать большие интервалы, что, в свою очередь, подразумевает меньшую точность.

Например, что является наибольшим двойным менее 1?

std::nexttoward(1.0, 0.0). Например. 0.999999999999999889 on Coliru.

+0

Спасибо. Я немного изменил этот вопрос, чтобы сделать его менее обманчивым, я надеюсь. – user1971455

2

Вы найдете гораздо более категорические заявления относительно противоположного направления от 1,0 Разницы между 1.0 и следующим большим числом документирована здесь:

std::numeric_limits<double>::epsilon()

Путем с плавающей точкой работы, следующее меньше число должно быть ровно в два раза меньше, чем 1.0, в качестве следующего большего числа.

2

Первый двойной IEEE ниже 1 может быть написан однозначно как 0.99999999999999989, но точно равен 0.9999999999999999988897769753748434595763683319091796875.

Расстояние не постоянное, оно зависит от экспоненты (и, следовательно, величины) от числа. В конце концов, разрыв становится больше, чем 1, что означает, что даже (не в отличие от нечетных - нечетных целых чисел, которые будут округлены) целые числа будут округлены несколько (или, в конечном итоге, много).

-2

При использовании представления с плавающей точкой IEEE 754 (двойной тип в C++) числа, близкие к точным целым, округляются до ближайшего целого и отображаются точно. Это правда?

Это неверно.

Какое расстояние должно быть близко к ближайшему int перед округлением?

Когда вы делаете двоичный файл преобразование строки число с плавающей точкой получает округляется до текущей точности (для printf семейства функций точности по умолчанию 6) с использованием текущего режима округления.

0

Двоичное представление большее число IEEE с плавающей запятой можно рассматривать как увеличение целочисленного представления:

Пример Hack (Intel):

#include <cstdint> 
#include <iostream> 
#include <limits> 

int main() { 
    double one = 1; 
    std::uint64_t one_representation = *reinterpret_cast<std::uint64_t*>(&one); 
    std::uint64_t lesser_representation = one_representation - 1; 
    std::cout.precision(std::numeric_limits<double>::digits10 + 1); 
    std::cout << std::hex; 
    std::cout << *reinterpret_cast<double*>(&lesser_representation) 
       << " [" << lesser_representation 
       << "] < " << *reinterpret_cast<double*>(&one_representation) 
       << " [" << one_representation 
       << "]\n"; 
} 

Выход:

0.9999999999999999 [3fefffffffffffff] < 1 [3ff0000000000000] 

При продвижении целочисленное представление в его пределы, разность последовательных чисел с плавающей запятой увеличивается, если изменяются биты экспоненты.

См. Также: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/

Смежные вопросы