Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Глючит float 
V
    Опции темы
=Женек=
Дата 13.9.2011, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: 1
Всего: 1



Господа, мне нужно округлить float до сотых. Именно округлить, а не отбросить числа после запятой. Поэтому printf не предлагать. Пробовал играться с floor и FormatFloat - выходит лажа.
Стал разбираться, что к чему, свел код до
Код

f=1.32455;
ShowMessage(f);

Получаю 1.32455003261566.

Что делать и кто виноват?
Пишу в Builder XE
PM MAIL   Вверх
artsb
Дата 13.9.2011, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(=Женек= @  13.9.2011,  19:19 Найти цитируемый пост)
Получаю 1.32455003261566.

Всё правильно. А что вы хотели увидеть?
Это "издержки производства" smile Это всё из-за представления машиной чисел с плавающей точкой. Тут ничего не поделаешь. Функции для округления есть. Нужно поискать. Если нужна большая точность, то используйте double.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
=Женек=
Дата 13.9.2011, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: 1
Всего: 1



Так мне не точность нужна. Мне нужно убрать лишние цифры.
Дано: 1.5453534234324
Хочу: 1.55
PM MAIL   Вверх
artsb
Дата 13.9.2011, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



RoundTo
Из справки:
Цитата

RoundTo(1234567, 3)  = 1235000 
 
RoundTo(1.234, -2)  = 1.23 
 
RoundTo(1.235, -2)  = 1.24 
 
RoundTo(1.245, -2)  = 1.24 

 



--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
volatile
Дата 13.9.2011, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 3
Всего: 85



Цитата(=Женек= @  13.9.2011,  19:19 Найти цитируемый пост)
Именно округлить, а не отбросить числа после запятой. Поэтому printf не предлагать.

Надо придумать другую причину, почему не нужно предлагать printf.
Потому-что, printf как раз таки округляет, а не отбрасывает.
http://liveworkspace.org/code/298ef71bc185...00f5ff1a91ca640


PM MAIL   Вверх
=Женек=
Дата 13.9.2011, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: 1
Всего: 1



Есть еще причина - printf преобразует результат в строку. А мне нужна цифра. Да, я понимаю что можно обратно отконвертировать, тем не менее, хочется писать код рационально и грамотно. А что-то мне подсказывает, что есть простой способ отбрасывать нули не преобразовывая число в строку

Код

RoundTo(1234567, 3)  = 1235000 
 
RoundTo(1.234, -2)  = 1.23 
 
RoundTo(1.235, -2)  = 1.24 
 
RoundTo(1.245, -2)  = 1.24 



Хрен там... выдает 1.24000000023432
Мне кажется что это какая-то глобальная настройка в билдере.

Добавлено через 2 минуты и 1 секунду
Закину параллельную удочку - а есть ли возможность настройить вормат ячейки в TStringGrid, чтобы она оторажал только округленные до сотых цифры?
PM MAIL   Вверх
artsb
Дата 13.9.2011, 23:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(=Женек= @  13.9.2011,  23:40 Найти цитируемый пост)
Хрен там... выдает 1.24000000023432

Это float. Вы никогда не получите число вида - 1.24


Цитата(=Женек= @  13.9.2011,  23:40 Найти цитируемый пост)
Закину параллельную удочку - а есть ли возможность настройить вормат ячейки в TStringGrid, чтобы она оторажал только округленные до сотых цифры? 

Рисуйте вручную. тогда и printf подойдёт ;)


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
volatile
Дата 13.9.2011, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 3
Всего: 85



Цитата(=Женек= @  13.9.2011,  23:40 Найти цитируемый пост)
хочется писать код рационально и грамотно

Если писать грамотно, то затею округлять флоаты до сотых - нужно признать абсолютно безграмотной.

Потому как там нет сотых в принципе, там двоичный плавающий формат...


PM MAIL   Вверх
=Женек=
Дата 13.9.2011, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: 1
Всего: 1



ладно, я думаю вы поняли что мне нужно. Мне нужно 2 цифры после запятой. Как это сделать - и в интернете есть и здесь мне написали. Да вот только глюк у меня нестандартный - даже принудительно приравняв переменную при ее отображении получается нечто другое. Как это решить?
PM MAIL   Вверх
volatile
Дата 14.9.2011, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 3
Всего: 85



Цитата(=Женек= @  13.9.2011,  23:54 Найти цитируемый пост)
Как это решить? 

=Женек=,  еще раз, медленно:
float просто физически не может содержать число строго равное двум десятичным числа после запятой.
Цитата(volatile @  13.9.2011,  23:51 Найти цитируемый пост)
там нет сотых в принципе, там двоичный плавающий формат...


Единственный выход, огруглять при выводе.
PM MAIL   Вверх
=Женек=
Дата 14.9.2011, 00:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: 1
Всего: 1



Я сдаюсь...
Вот строка в которой заполняется ячейка StringGrid

Код

ParametricTable->Cells[0][2]=(float)(PreHeat_Temperature-Ambient_Temperature)/PreHeat_Time;


Исходные переменные типа int
Ткните пальцем, че сделать то?



Это сообщение отредактировал(а) =Женек= - 14.9.2011, 00:19
PM MAIL   Вверх
volatile
Дата 14.9.2011, 01:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 3
Всего: 85



Цитата(=Женек= @  14.9.2011,  00:18 Найти цитируемый пост)
че сделать то?

Перевести в текст и вывести.

Код

ParametricTable->Cells[0][2] = FloatToStrF(...);
Билдера нет, поэтому точный вызов не скажу. см. описание FloatToStrF();

Добавлено через 2 минуты и 38 секунд
Или, как вариант:
Код

char buf [32];
sprintf (buf, "%.2f", double(PreHeat_Temperature-Ambient_Temperature)/PreHeat_Time);
ParametricTable->Cells[0][2] = buf;

PM MAIL   Вверх
rodnover
Дата 14.9.2011, 06:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: нет
Всего: 10



http://www.softelectro.ru/ieee754.html

Вот статейка по описанию формата двоичных вещественных чисел. Там и погрешности есть и описывается, почему так.


Для точных значений лучше использовать специальные классы типа Currency В Delphi или numeric в SQL.

В простейшем случае для числа сделать структуру в которой хранить в 2х int целую и вещественную часть.

Добавлено через 1 минуту и 6 секунд
вот еще хорошая статья

http://www.yur.ru/science/computer/IEEE754.htm
PM MAIL   Вверх
=Женек=
Дата 14.9.2011, 08:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 548
Регистрация: 20.2.2005

Репутация: 1
Всего: 1



rodnover, спасибо за статью, познавательно.
volatile, тоже спасибо, все получилось.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.1069 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.