2012-02-24 2 views
3

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

int YYYY, JJJ, HH, MM; 

float datenumber = (YYYY*360.0f)+(JJJ*1.0f)+((HH*1.0f)+(MM/60.0f))/24.0f; 

Используя значения 2001, 083, 22, 32 я должен получить результат 724043.939. Вместо этого я получаю 724044.

У меня есть все функции, отлитые как поплавки. Почему они остаются целыми?

Редактировать Да, я показывал вывод с помощью cout. setprecision решила проблему, спасибо.

+5

Как вы просматриваете окончательное значение; debugger, 'printf()'? – trojanfoe

+1

Как вы печатаете результат? Возможно, проблема в вашем заявлении на печать – vmpstr

+0

Согласно [моему тесту] (http://ideone.com/KhmMZ), 'printf' отображает ожидаемый результат, но' cout' отображает «неправильное» значение. –

ответ

0

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

Почему бы не объявить их как поплавки изначально?

float YYYY, JJJ, HH, MM; 
+1

Он использует 'float' константы в качестве других операндов в' * 'и'/', поэтому' int 'повышается до' float' до того, как эти операции будут выполнены. Это означает, что то, о чем вы говорили, не является проблемой. EDIT: То, что Дэн Ф говорит ниже, является правильным. –

+1

Не всегда ли выполняется арифметика с плавающей запятой, если используется float? поэтому 'int * float' не будет усекать, если вы не нажмете ... –

+0

Ах да, должен был знать ... мой плохой – wvm2008

1

Вам нужно сделать TWO вещи:

  1. Установите точность до максимума (cout.setprecision(16))
  2. Преобразовать в double (double dateNumber и YYYY*360.0)
+0

Вот что [мой тест] (http://ideone.com/KhmMZ). Там должно быть больше, чем это. –

+0

@RobKennedy: Я думаю, что изменить его, чтобы удвоить и изменить точность, исправить это. – Jacob

0

Следующая может быть причиной- 1. Можете ли вы печатать g они ошибочно. 2. Разделив целое число, используйте вместо него float.

Примера-Вместо разделения на 200 деления на 200,0

3

Проблемы не в своем номере или ваш расчете. Это только так, как вы его показываете. cout решил, что вам достаточно 6 цифр. Используйте setprecision, если хотите больше.

std::cout << std::setprecision(10) << datenumber; 

demo

+0

Нет, здесь есть что-то более увлекательное. Проверьте это: http://codepad.org/TfRlPfOh – Jacob

+0

@Jacob, вы получаете этот вывод, потому что как 'float', значение переменной * действительно равно * 432000. У него недостаточно точности, чтобы удерживать остальные от стоимости. См. [Мою точную страницу с плавающей точкой] (http://www.cs.wisc.edu/~rkennedy/exact-float?number=432000.0034722222). –

+0

Это не было 'cout', что решил, что 6 было достаточно; это был стандарт C++. Шесть - это точность по умолчанию для любого нового потомка basic_ios. –

0

Судя по мере ввода и вывода значений в примере вы предоставили в ответ Беньямина, я готов поспорить, что этот вопрос просто плавающей точкой. Просто потому, что вы объявляете что-то как float, не означает, что он может обрабатывать любой размер. Проблема заключается в том, что ваш компонент года (1200 * 360 = 432000) больше, чем ваш компонент MM (5/60/24 = .00347222). Десятичная часть из MM-части просто игнорируется, поскольку поплавки не так точны. Попробуйте добавить .000001 в 123456789 в качестве поплавка и посмотреть, что ваш выход

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