Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.05.21;
Скачать: CL | DM;

Вниз

Странное поведение дельфи :(   Найти похожие ветки 

 
MegaVolt ©   (2006-04-28 12:12) [0]

Вот пример функции которая при dbedMass.Text = 10.135 (ди и при других тоже) почему то идёт по ветке else.
Функция должна округлять до второго знака с учётом третьего знака.
Глюк есть под D7+WinXP (D7 без апдейтов)
Под D5 глюка нет.
Проверьте есть ли у кого похожий глюк?


procedure TfmProducts.dbedMassExit(Sender: TObject);
var Mass: Double;
   xFrac: Real;
begin
 //
 Mass:= StrToFloat(dbedMass.Text);

 if Mass > 10 then
 begin
   xFrac:= Frac(Mass*100);
   xFrac:= xFrac*10;
   if (xFrac > 5) or (xFrac = 5) then
     Mass:= Int((Mass*100) + 1)/100
   else Mass:= RoundTo(Mass, -2);

   dbedMass.Text:= FloatToStr(Mass);

 end;


 
MegaVolt ©   (2006-04-28 12:15) [1]

Упс... Винда 2000 а не ХР хотя вряд ли она влиеят.


 
Desdechado ©   (2006-04-28 12:20) [2]

какие-то невразумительные преобразования
может, проще поиграть со строкой, раз уж она на вход подана?
или использовать готовые функции


 
MegaVolt ©   (2006-04-28 12:27) [3]

>какие-то невразумительные преобразования

Что невразумительного. Умножили на 100, округлили с учётом 3 знака, поделили на 100.

>может, проще поиграть со строкой, раз уж она на вход подана?

Вопрос не как правильно округлить а почему 5<>5

>или использовать готовые функции

А что за функция округляет по математическим правилам с учётом далее стоящих знаков?


 
Desdechado ©   (2006-04-28 13:17) [4]

> почему 5<>5
это азы
сравнение чисел с плавающей точкой никогда не даст истину, ибо это особенности способа их машинного представления


 
Сергей М. ©   (2006-04-28 13:27) [5]


> MegaVolt ©   (28.04.06 12:27) [3]


SetRoundMode + RoundTo


 
icWasya ©   (2006-04-28 14:04) [6]

после вот этого
  xFrac:= Frac(Mass*100);
  xFrac:= xFrac*10;
у меня  
xFrac = 4.999999999999787

Прочти и раскрась
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1217


 
MegaVolt ©   (2006-04-28 14:35) [7]

>> почему 5<>5
>это азы сравнение чисел с плавающей точкой никогда не даст истину, ибо это особенности способа их машинного представления

Ну не совсем азы ибо 5 так же как и 0,5 могут быть точно представлены в двоичном виде. В отличии например от 0,1.

>SetRoundMode + RoundTo

Судя по раскраске [6] они так же глючат

>icWasya
>после вот этого
>  xFrac:= Frac(Mass*100);
>  xFrac:= xFrac*10;
>у меня  
>xFrac = 4.999999999999787

А ты это как смотрел? Потому что отладчик вроде показывает 5. Если навестись мышой на число. Получается отладчик округляет малость?

За раскраску огромное спасибо правдя я её уже сам нашел :)

Кстати почему глючит сей пример я уже понял: 10.135 нельзя точно представить в двоичном виде. И хотя после умножения 1013.5 уже представим в двоичном виде но реально у нас будет некое другое число отличное от 1013.5

Любопытно почему в D5 всё нормально :)


 
han_malign ©   (2006-04-28 14:55) [8]

>никогда не даст истину
- ну это ты погорячился.

var _real: real;
begin
      _real:= 5;
      if(_real = 5)then ...


> ибо 5 так же как и 0,5 могут быть точно представлены в двоичном виде


ну ежели мы "прекрасно знаем" двоичное представление вещественных чисел - разбирайся

------------------------------80---------------------0 - bit
Extended StrToFloat("10,135")
>>  1.01350000000000E+0001 : 4002A228F5C28F5C28F6
double        Mass:=
>>  1.01350000000000E+0001 :        4024451EB851EB85
Extended      (Mass*100)
>>  1.01350000000000E+0003 : 4008FD5FFFFFFFFFFE80
Extended      Frac()
>>  4.99999999999979E-0001 : 3FFDFFFFFFFFFFF40000
D7: real = double
real=double   xFrac:=
>>  4.99999999999979E-0001 :       3FDFFFFFFFFFFE80
real=double   xFrac:=xFrac*10
>>  4.99999999999979E+0000 :       4013FFFFFFFFFF10
D5: real = real48
real=real48   xFrac:=
>>  5.00000000000000E-0001 :              000000000080
real=real48   xFrac:=xFrac*10
>>  5.00000000000000E+0000 :             200000000083


 
MegaVolt ©   (2006-04-28 15:18) [9]

Всё равно не совсем понял почему под D5 вдруг ошибки представления ищезли. Ну и что с того что тип другой?


 
Desdechado ©   (2006-04-28 15:38) [10]

> могут быть точно представлены в двоичном виде
снова азы: "могут" не значит "будут"

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


 
MegaVolt ©   (2006-04-28 16:35) [11]

>снова азы: "могут" не значит "будут"

Упс. А это откуда? Что то я не помню чтобы перевод числа в двоичную форму имел несколько вариантов решения.

>проверка на точное равенство бессмысленна

Если присмотрется то в примере сравнение идёт на >= или что эквивалентно not < Я надеюсь меньше не запрещёна для чисел с плавающей запятой?

Например пока из вышеприведённого я понял следуещее: при переводе из одного формата в другой компилятор/сопроцессор иногда сам производит округление по неким своим правилам. Где бы почитать эти правила?

P.S. Господа давайте перестанем тыкаться азами. Высшее радиотехническое образование + 10 лет работы с программируемой логикой позволяют мне понимать что есть представление чисел в двоичном виде какие есть особенности при расчётах и пр... А так же я знаю что есть байт и бит :)
А вот в относительности связки Intel+MicroSoft есть пробелы. Поэтому и прошу пояснить. Почему вдруг в зависимости от типа компилятора результаты отличаются.


 
Desdechado ©   (2006-04-28 17:12) [12]

> перевод числа в двоичную форму имел несколько вариантов решения
перевод - нет, а представление - запросто
одно и то же действительное число с (еще раз подчеркиваю) плавающей точкой может быть представлено разными способами

если не помнишь понятия мантиссы, основания и порядка, то поищи в гугле
так вот - в разных случаях это представление может быть как с потерей точности в незначащих разрядах, так и без оного
как эти случаи случаются, я не знаю (увы), но знания об их возможности мне достаточно, чтобы не сравнивать на равенство действительные числа


 
MegaVolt ©   (2006-04-28 17:24) [13]

>если не помнишь понятия мантиссы, основания и порядка, то поищи в гугле

Ещё раз повторюсь эти понятия мне знакомы ещё со школьной скамьи и программируемого калькулятора МК-61

Число 0,5 это 2^-1 и представляется точно в любом представлении так как у него нет незначащих младших разрядов.

Вот у 0,1 есть. Это бесконечное двоичное число в плане количества знаков после запятой. Тут действительно могут быть хитрости.


 
Desdechado ©   (2006-04-28 17:50) [14]

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

все, я устал объяснять
если будешь меньше растопыривать пальцы "ещё со школьной скамьи", то, возможно, освежишь свои знания и поймешь, что учиться нужно всю жизнь
и не стыдиться этого


 
Anatoly Podgoretsky ©   (2006-04-29 15:27) [15]

Высшее радиотехническое образование + 10 лет работы все насмарку


 
MegaVolt ©   (2006-05-03 13:42) [16]

>это у числа нет, а у способа его представления (типа данных) - есть.
>читай справку про число значащих разрядов в типах с плавающей точкой.
>если будешь меньше растопыривать пальцы то, возможно, освежишь свои знания и поймешь, что учиться нужно всю жизнь
>Высшее радиотехническое образование + 10 лет работы все насмарку

Господа специалисты я не прочь поучится да вот что то никто простой пример на пальцах привести не может. Как это 0,5 в двоичном представлении выглядящая как 1 и степень -1 может быть представлена неточно за счёт ограниченности числа разрадов в конкретном представлении числа?

Господа кончаем понтовать и приводим пример или всё вышесказанное считаю просто отсутствием чего сказать.



Страницы: 1 вся ветка

Текущий архив: 2006.05.21;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.039 c
15-1145120090
Mozart
2006-04-15 20:54
2006.05.21
Первичный ключ


2-1146665445
Елизавета
2006-05-03 18:10
2006.05.21
Подскажите где взять иконки


2-1146203130
Негодяй
2006-04-28 09:45
2006.05.21
Стереть саму себя


2-1146231190
Начинающий5
2006-04-28 17:33
2006.05.21
выключить компьютер


6-1129636325
Cosinus
2005-10-18 15:52
2006.05.21
Как отследить активность определенного порта?