LINUX.ORG.RU

вопрос про float


0

0

есть программка:
#include<stdio.h>
#include<stdlib.h>

int main()
{
char *val = "43.3";
float fv;

fv = strtod(val, NULL);
printf("val %d\n", (int)(fv*10.0));

return 0;
}
выводит 432, а должно быть 433. Как это можно победить без использования round и т.п.?

anonymous

> printf("val %d\n", (int)(fv*10.0));

заменить на

printf("val %f.0\n", fv*10.0);

вроде бы :-))

r_asian ★☆☆
()

после строчки

fv = strtod(val, NULL);

fv = 43. В данном случае происходит потеря точности из-за преобразования типа float в тип int. Вообще float рекомендуется использовать только при вводе и выводе данных, а для вычислений лучше double использовать.

armageddon
()
Ответ на: комментарий от armageddon

нет, при вызове stdtod никаких преобразований в int не происходит, смотри man strtod.

Проблема заключается в том, что значение fv после вызова strtod равно 43.299999(9), в чем можно убедится, добавив после строку

printf ("%f\n", fv);

Так что без round здесь никак не обойтись.

Shmuma
()
Ответ на: комментарий от Shmuma

Хотя нет, вру, можно без round. Заменить 

fv = atof(val); 

на 

fv = atof(val)+1e-5;

Насколько это корректно, не знаю, но на указанном примере работает. 

Shmuma
()

fv == 43.299999, fv * 10 == 432.99999, после отбрасывания дробной части получается 432.

Простецкий способ такое побеждать - прибавлять 0.5 перед переводом в int.

tailgunner ★★★★★
()
Ответ на: комментарий от Shmuma

а вот как заставить strtod записывать в fv значение 43.3, а не 43.299999(9)? или это невозможно в принципе? не уж то придется писать свою реализацию strtod?

anonymous
()
Ответ на: комментарий от anonymous

> а вот как заставить strtod записывать в fv значение 43.3, а не 43.299999(9)?

Никак

> или это невозможно в принципе?

Насколько я помню курс "Представление данных" родного ПТУ, невозможно в принципе 8)

> не уж то придется писать свою реализацию strtod?

Не придется, ибо см. выше ;)

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

> а вот как заставить strtod записывать в fv значение 43.3, а не 43.299999(9)?

есть только один надёжный спопоб -- использовать специальный тип данных для десятичных дробей, как в COBOL'е.

иначе float хранится в виде <целое>*2^(-<другое целое>), и кстати сказать девять в периоде там вовсе даже не возникает.

scotinomys
()

Я, в своё время, создавал структуру с двумя членами: целой частью и мантиссой (оба - целые числа), потом писал все необходимые функции (сложение, умножение и т.д.).

На плюсах можно создать класс, а вообще наверняка есть готовые библиотеки. И ещё можно на bc посмотреть, у него, если не ошибаюсь, таких проблем нет.

Davidov ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.