![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Странное поведение дельфи :( [D7, WinXP]
MegaVolt © (2006-04-28 12:12:00)Вот пример функции которая при 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-05-03 13:42:00) [1]>это у числа нет, а у способа его представления (типа данных) - есть.
>читай справку про число значащих разрядов в типах с плавающей точкой.
>если будешь меньше растопыривать пальцы то, возможно, освежишь свои знания и поймешь, что учиться нужно всю жизнь
>Высшее радиотехническое образование + 10 лет работы все насмарку
Господа специалисты я не прочь поучится да вот что то никто простой пример на пальцах привести не может. Как это 0,5 в двоичном представлении выглядящая как 1 и степень -1 может быть представлена неточно за счёт ограниченности числа разрадов в конкретном представлении числа?
Господа кончаем понтовать и приводим пример или всё вышесказанное считаю просто отсутствием чего сказать.
Anatoly Podgoretsky (2006-04-29 15:27:00) [2]Высшее радиотехническое образование + 10 лет работы все насмарку
Desdechado (2006-04-28 17:50:00) [3]> нет незначащих младших разрядов
это у числа нет, а у способа его представления (типа данных) - есть.
читай справку про число значащих разрядов в типах с плавающей точкой.
все, я устал объяснять
если будешь меньше растопыривать пальцы "ещё со школьной скамьи", то, возможно, освежишь свои знания и поймешь, что учиться нужно всю жизнь
и не стыдиться этого
MegaVolt (2006-04-28 17:24:00) [4]>если не помнишь понятия мантиссы, основания и порядка, то поищи в гугле
Ещё раз повторюсь эти понятия мне знакомы ещё со школьной скамьи и программируемого калькулятора МК-61
Число 0,5 это 2^-1 и представляется точно в любом представлении так как у него нет незначащих младших разрядов.
Вот у 0,1 есть. Это бесконечное двоичное число в плане количества знаков после запятой. Тут действительно могут быть хитрости.
Desdechado (2006-04-28 17:12:00) [5]> перевод числа в двоичную форму имел несколько вариантов решения
перевод - нет, а представление - запросто
одно и то же действительное число с (еще раз подчеркиваю) плавающейточкой может быть представлено разными способами
если не помнишь понятия мантиссы, основания и порядка, то поищи в гугле
так вот - в разных случаях это представление может быть как с потерей точности в незначащих разрядах, так и без оного
как эти случаи случаются, я не знаю (увы), но знания об их возможности мне достаточно, чтобы не сравнивать на равенство действительные числа
MegaVolt (2006-04-28 16:35:00) [6]>снова азы: "могут" не значит "будут"
Упс. А это откуда? Что то я не помню чтобы перевод числа в двоичную форму имел несколько вариантов решения.
>проверка на точное равенство бессмысленна
Если присмотрется то в примере сравнение идёт на >= или что эквивалентно not < Я надеюсь меньше не запрещёна для чисел с плавающей запятой?
Например пока из вышеприведённого я понял следуещее: при переводе из одного формата в другой компилятор/сопроцессор иногда сам производит округление по неким своим правилам. Где бы почитать эти правила?
P.S. Господа давайте перестанем тыкаться азами. Высшее радиотехническое образование + 10 лет работы с программируемой логикой позволяют мне понимать что есть представление чисел в двоичном виде какие есть особенности при расчётах и пр... А так же я знаю что есть байт и бит :)
А вот в относительности связки Intel+MicroSoft есть пробелы. Поэтому и прошу пояснить. Почему вдруг в зависимости от типа компилятора результаты отличаются.
Desdechado (2006-04-28 15:38:00) [7]> могут быть точно представлены в двоичном виде
снова азы: "могут" не значит "будут"
и еще раз - для чисел с плавающейточкой проверка на точное равенство бессмысленна
и пока не поймешь, будешь удивляться и ловить глюки, а также тумаки от пользователей
MegaVolt (2006-04-28 15:18:00) [8]Всё равно не совсем понял почему под D5 вдруг ошибки представления ищезли. Ну и что с того что тип другой?
han_malign (2006-04-28 14:55:00) [9]> никогда не даст истину
- ну это ты погорячился.
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 14:35:00) [10]>> почему 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 всё нормально :)
icWasya (2006-04-28 14:04:00) [11]после вот этого
xFrac:= Frac(Mass*100);
xFrac:= xFrac*10;
у меня
xFrac = 4.999999999999787
Прочти и раскрась
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1217
Сергей М. (2006-04-28 13:27:00) [12]
> MegaVolt © (28.04.06 12:27) [3]
SetRoundMode + RoundTo
Desdechado (2006-04-28 13:17:00) [13]> почему 5<>5
это азы
сравнение чисел с плавающей точкой никогда не даст истину, ибо это особенности способа их машинного представления
MegaVolt (2006-04-28 12:27:00) [14]>какие-то невразумительные преобразования
Что невразумительного. Умножили на 100, округлили с учётом 3 знака, поделили на 100.
>может, проще поиграть со строкой, раз уж она на вход подана?
Вопрос не как правильно округлить а почему 5<>5
>или использовать готовые функции
А что за функция округляет по математическим правилам с учётом далее стоящих знаков?
Desdechado (2006-04-28 12:20:00) [15]какие-то невразумительные преобразования
может, проще поиграть со строкой, раз уж она на вход подана?
или использовать готовые функции
MegaVolt (2006-04-28 12:15:00) [16]Упс... Винда 2000 а не ХР хотя вряд ли она влиеят.