2014-12-04 2 views
3

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

2-(2^-23)       Exponent Bits 
1.99999988079071044921875 * (1.7014118346046923173168730371588e+38) = 
    3.4028234663852885981170418348451e+38 

Это должно быть наибольшее число одинарной точности с плавающей точкой:

340282346638528859811704183484510000000.0 

Так,

float i = 340282346638528859811704183484510000000.0; 
printf(TEXT, "Float %.38f", i); 
Output: 340282346638528860000000000000000000000.0 

Очевидно, число округляется вверх, так что я пытаюсь выяснить, точно, что происходит.

Мои вопросы: В документации по Википедии указано, что 3.4028234663852885981170418348451e+38 является наибольшим числом, которое может быть представлено в неподвижной точке IEEE-754.

Это число, хранящееся в регистре с плавающей запятой = 0 11111111 11111111111111111111111, и оно просто не отображается неправильно?

Если я пишу printf(TEXT, "Float %.38f", FLT_MAX);, я получаю тот же ответ. Возможно, компьютер, который я использую, не использует IEEE-754?

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

Возможно, показатель Mantissa * Expoment вызывает ошибки расчета? Если это так, то 340282346638528860000000000000000000000.0 будет самым большим числом, которое может быть точно представлено без ошибок расчета. Думаю, это имело бы смысл. Просто нужно благословение.

Спасибо,

+2

"0 11111111 11111111111111111111111" является NAN. Подозреваю, что вы хотите «0 11111110 11111111111111111111111» – chux

+0

'FLT_MAX' - это то, что вы думаете. Ваш 'printf()' показывает его приближение. Чтобы узнать, что _exactly_ является десятичным значением 'FLT_MAX', вам нужно использовать другой код. – chux

+0

Википедия также говорит: «Это дает от 6 до 9 достоверных цифр десятичной цифры», поэтому в повседневном использовании в качестве приближения некоторого близкого значения, пытаясь напечатать все цифры, как если бы это было определенное целое число с такой величиной, было немного глупо. Ни один из предыдущих 10^~ 30 целых чисел не был представлен. Интересно, однако, что printf показывает количество цифр, которые обычно имеют смысл в значении с двойной точностью - моя догадка заключается в том, что ваша реализация заставляет float удваивать, генерирует разумное представление этого и прокладки с 0s до требуемой длины , –

ответ

4

Похоже, виновником является printf() (я предполагаю, потому что float неявно преобразуется в double при передаче к нему):

#include <iostream> 
#include <limits> 

int main() 
{ 
    std::cout.precision(38); 
    std::cout << std::numeric_limits<float>::max() << std::endl; 
} 

Выход:

3.4028234663852885981170418348451692544e+38 
+0

Мне нужно попробовать это. это значение, тогда это должно быть заявление printf(). –

+0

Ответ, который я получаю с использованием вашего кода, несколько отличается. 34028234663852887000 ... Так что это должно быть различие с компилятором/компьютером. это с заявлением printf()? –

3

С float как binary32, самым большим конечным float является

340282346638528859811704183484516925440,0

printf("%.1f", FLT_MAX) не обязан печатать точно 38+ значащие цифры, так как видит выход ниже не является неожиданным.

340282346638528860000000000000000000000,0

printf() будет печатать с плавающей точкой точно DECIMAL_DIG значащих цифр. DECIMAL_DIG находится на наименее 10.Если указано больше, чем DECIMAL_DIG, то соответствующий признак printf() может округлить результат в какой-то момент. C11dr §7.21.6.1 6 подробно рассматривается.

+0

Интересно тогда, что вопрос утверждал, что он был 340282346638528859811704183484510000000.0 - но значение менее возбудило, учитывая, что вопрос действительно ищет объяснения гораздо меньшего точность, показанная printf. Хороший ответ. Я подозреваю, что printf() может быть разрешено отображать больше или даже обязано ... только эта конкретная реализация, не позволяющая ... но я не нашел ссылку. –

+0

@Tony D Нашел спецификацию и исправил сообщение. Спецификация немного техническая, поэтому я не процитировал ее, но IMO, это означает, что по крайней мере цифры DECIMAL_DIG должны быть точно презентабельными. Показаны более значимые цифры, они должны быть правильными (либо с ограничениями следующего самого высокого, либо на следующий минимум). – chux

+0

ох прохладно - хорошо знать. Вы столкнулись с этим вопросом :-). Приветствия. –

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