Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Trunc его глюки и борьба с ними. Нужна помощь. 
V
    Опции темы
ivan219
  Дата 1.10.2007, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Код

.
.
Temperatura(12);
.
.
.
procedure TFNPC01S.Temperatura(Tem: Real); // Tem имеет значения в диапазоне 999.9 ... 000.0
var
  Tem1: Real;
  I: Integer;
  S: String;
begin
 Tem1 := Trunc(Tem * 10); // Отбрасываем всё кроме первого знака после запятой получаем 0000 ... 9999.
 for I := 1 to 4 do  // Цикл на 4 знака 0000 ... 9999.
  begin
   Tem1 := Tem1 / 10;  // Определяем число после запятой.
   S := S + IntToStr(Trunc((Tem1 - Trunc(Tem1)) * 10)); // Преобразуем.
  end;
 Label1.Caption := S; // Выводим.
end;

На выходе имеем 011 хотя должно быть 021 если сделать так:
Код

Temperatura(13);

то получается правильно т.е. 031 вобщем так как и долно быть, такиеже глюки наблюдаются и с другими числами 4, 7, 9 на выходе получаем на 1 меньше.

Возможноли это обойти без перевода в String и дольнейшего разбота строки т.е. напрямую работать с числами???

Это сообщение отредактировал(а) ivan219 - 1.10.2007, 11:53
PM MAIL ICQ   Вверх
Coder
Дата 1.10.2007, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



если я правильно понял, то:
Код

str:=FormatFloat('0',Tem);
while length(str)<3 do
  str:='0'+str;
Label1.Caption := str;

PM MAIL   Вверх
skyboy
Дата 1.10.2007, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

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



это не глюки, это особенности. и не у trunc, а у представления вещественных чисел. 
то, что real(some - trunc(some)) * 10 выводится как "2", это не значит, что там реально хранится 2. Просто число, достаточно близкое к 2(1,999999999). И при выводе видим 2, а при обработке воспринимаем как "1,999999999". Соотвественно, trunc, которое просто отбросит дробную часть, получит 1, а не "2".
Т.е. у меня в Delphi 7 
Код

var s: real;
...
  ShowMessage(floattostr((1.2 - 1) * 10));
  ShowMessage(IntToStr(Trunc((1.2 - Trunc(1.2)) * 10)));
  s:= 1.2;
  ShowMessage(IntToStr(Trunc((s - Trunc(s)) * 10)));
...

Первые два вернут "2"(видимо, сказывает оптимизация), а третие вернет "1". В принципе, то же, что и в твоем коде, но только можно увидеть, что при работе с константами отклонений не наблюдается.
PM MAIL   Вверх
ivan219
  Дата 1.10.2007, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Печально  smile с Roun таже история только на оборот, придётся с Snring возится smile 
Цитата(Coder @  1.10.2007,  12:06 Найти цитируемый пост)
если я правильно понял, то:

ну почти в идеале мне ндо чтобы на выходе было 4 переменных Integer переменую S я ввёл для вас так как мой код отличается.
Я банально хотел избавится от лишний преобразований Real -> String -> [1..4] Integer но видать не удастся smile 

Всем спасибо!!!

Это сообщение отредактировал(а) ivan219 - 1.10.2007, 12:24
PM MAIL ICQ   Вверх
ivan219
  Дата 1.10.2007, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(ivan219 @  1.10.2007,  11:47 Найти цитируемый пост)
Возможноли это обойти без перевода в String и дольнейшего разбота строки т.е. напрямую работать с числами???

Можно  smile надо только до выполнения Trunc прибавить к числу 0.00001 (больше или менше всё зависит от кода и чисел) тем самым искуственно делаем завышенное число что приводит к нужному результату smile 
Код

.
.
Temperatura(12);
.
.
.
procedure TFNPC01S.Temperatura(Tem: Real); // Tem имеет значения в диапазоне 999.9 ... 000.0
var
  Tem1: Real;
  I: Integer;
  S: String;
begin
 Tem1 := Trunc(Tem * 10 + 0.00001); // Отбрасываем всё кроме первого знака после запятой получаем 0000 ... 9999.
 for I := 1 to 4 do  // Цикл на 4 знака 0000 ... 9999.
  begin
   Tem1 := Tem1 / 10;  // Определяем число после запятой.
   S := S + IntToStr(Trunc((Tem1 - Trunc(Tem1)) * 10 + 0.00001)); // Преобразуем.
  end;
 Label1.Caption := S; // Выводим.
end;

 smile 

Это сообщение отредактировал(а) ivan219 - 1.10.2007, 13:34
PM MAIL ICQ   Вверх
stab
Дата 1.10.2007, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1839
Регистрация: 1.1.2003

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



ivan219, долго смотрел на код.. что он делает? smile


--------------------
6, 6, 6 - the number of the beast.
PM MAIL WWW   Вверх
Alexeis
Дата 1.10.2007, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



ivan219, случайно не переписываешь функцию RoundTo для округления к десяткам, сотым?


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
skyboy
Дата 1.10.2007, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

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



смотрим "правильные" тестовые данные:
Цитата

13 -> 031
12 -> 021

т.е. происходит реверс строки с впередиидущем нулем smile хитро!
PM MAIL   Вверх
ivan219
  Дата 1.10.2007, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Я же написал:
Цитата(ivan219 @  1.10.2007,  12:23 Найти цитируемый пост)
переменую S я ввёл для вас так как мой код отличается.

А мой код если интересно вот:
Код

procedure TFNPC01S.Temperatura(Tem: Real);
var
  Tem1: Real;
  I: Integer;
  SS: TSevenSegment;
begin
 Tem1 := Trunc(Tem * 10 + 0.00001); // Отбрасываем всё кроме первого знака после запятой получаем 0000 ... 9999.
 for I := 4 downto 1 do  // Цикл на 4 знака 0000 ... 9999.
  begin
   if Tem1 < 1 then Break;
   SS := FindComponent('SevenSegment' + IntToStr(I)) as TSevenSegment;
   Tem1 := Tem1 / 10;  // Определяем число после запятой.
   SS.Segment := Trunc((Tem1 - Trunc(Tem1)) * 10 + 0.00001); // Преобразуем.
  end;
end;

Работает так как надо smile 
TSevenSegment это мой компонент семисегментного индикатора smile и так как ваш компилатор покозалбы большую фигу я перелелал под Label чтоб лишних вопросов небыло smile


Это сообщение отредактировал(а) ivan219 - 1.10.2007, 15:29

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  SS.gif 0,54 Kb
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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