![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Значит так друзья. Пишу программу и столкнулся с "детской" процедуркой. Код немного переделанный (что бы понятно было), но суть ясна. Значит вот он:
Так вот сколько вы ожидаете увидеть в Label1? А ожидал 3. А там 2! Вроде встречался с функцией Round и знаю, что она должна округлять по извесным правилам. Т.е. 0.5 округляется до 1, а 1.5 до 2. Но почему же тогда 1 + 2 = 2 ? Может кто встречался с таким? Это хорошо, что у меня так получилось, что я сразу нашел. А ведь из-за этого погут все расчеты пойти на смарку. ![]() -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
RA |
|
||||
![]() Брутальный буратина ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3497 Регистрация: 31.3.2002 Где: Лес Репутация: 14 Всего: 115 |
0.5 округляется до 0. Добавлено @ 04:45 попробуй вместо Round использовать Ceil, ибо чеил округляет число в сторону увеличения, а round до ближайшего целого.
Это сообщение отредактировал(а) RAdmin - 10.3.2005, 04:56 |
||||
|
|||||
SPrograMMer |
|
||||
![]() Спамер :) ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 5.11.2004 Где: Краснодар Репутация: 2 Всего: 6 |
Из того модуля Math:
Попробуй сказать:
-------------------- животное = зверь законченный гентушник |
||||
|
|||||
Poseidon |
|
||||||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
RAdmin
то получим не желанные 5, а 4!
Не подходит! Нужно именно округлять по правилам (< 5 в меншую, >=5 в большую сторону). Конечно можно устроить проверку символа после запятой и по нему определять, куда округлять в большую (Ceil) или меншую (Trunc) сторону. Но все же хотелось бы разобраться, почему так происходит? ![]() В общем-то начиная эту тему, я не ставил себе целью найти помощь. В Delphi есть ряд математических функций, каторые могут справится с округлением. Можно еще применить всякие хитрости (допустим, предложенная мной проверка символа после запятой). Целью было узнать, почему так происходит. Почему Round округляет не так, как от нее ждут? Есть у кого мнение по этому поводу? -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
||||||
|
|||||||
<Spawn> |
|
|||
![]() Око кары:) ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2776 Регистрация: 29.1.2003 Где: Екатеринбург Репутация: 44 Всего: 64 |
Это не ошбика Борладн это особенность представления дробных чисел в FPU, и, если я правильно помню, то именно от того, что 0.5(и некоторые другие, приведенные тобой числа), не могут быть представлены конечной двоичной дробью, в результате чего в реальности число ставновится чем то вроде - 0.499999999999999999999999999999999. Где то на этом форуме недавно была ссылка на статью, хорошо это обьясняющюю, но найти ее, к сожалению, я не могу. Это сообщение отредактировал(а) <Spawn> - 11.3.2005, 06:06 -------------------- "Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков. |
|||
|
||||
Alex |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4147 Регистрация: 25.3.2002 Где: Москва Репутация: 80 Всего: 162 |
http://forum.vingrad.ru/index.php?showtopic=44001&hl= -------------------- Написать можно все - главное четко представлять, что ты хочешь получить в конце. |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: нет Всего: 454 |
Хотя это - следствие представления числа в бине, но попутно замечу, что есть термин "бухгалтерское округление" - то что ОБЯЗАНО использоваться в любых денежных расчетах. Так вот, по нему половинка округляется не вниз и не вверх, а к БЛИЖАЙШЕМУ ЧЕТНОМУ. И это определено соотв. стандартом, международным кстати. Вот такие пироги... -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
RST8 |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 232 Регистрация: 8.12.2004 Репутация: 1 Всего: 1 |
Так чем же можно округлить число по правилам до какого нибудь знака после запятой?
--------------------
Посадка, с места которой можно уйти на собственных ногах, считается удачной! |
|||
|
||||
Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 25 Всего: 55 |
Дык неужели из темы не стало ясно что все зависит от того какие правила имеются ввиду. Много их, правил-то, и все разные. -------------------- Все знать невозможно, но хочется |
|||
|
||||
SPrograMMer |
|
||||
![]() Спамер :) ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 5.11.2004 Где: Краснодар Репутация: 2 Всего: 6 |
![]() У меня что-то родилось: Пусть наше 0.5 представляется в виде 0.499999999999999999999, а нам нужно всё это округлить до целых. Поступаем следующим образом: 1. Округлаем до того знака, до которого задавли число, то есть, в числе 0.5 одна цифра после запятой => округляем до одного знака после запятой (можно RondTo`ом воспользоваться). Вот только что при этом получится? по идее 0.49999999999999 должно превратиться в 0.5 2. Округлаем (тут же) полученное число до нужного.
-------------------- животное = зверь законченный гентушник |
||||
|
|||||
Петрович |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 25 Всего: 55 |
Посмотри описания функций RoundTo и SimpleRoundTo:
А если проще: Функции RoundTo и SimpleRoundTo используют несколько разные алгоритмы в случаях, когда округляемое число расположено точно посередине между двумя значениями, имеющими заданное число значащих разрядов. Функция RoundTo в этом случае округляет до четного числа. А функция SimpleRoundTo в этом случае округляет до большего числа. Так что выбирай то что тебе надо. -------------------- Все знать невозможно, но хочется |
||||
|
|||||
Santer |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 10.3.2005 Репутация: нет Всего: нет |
Вот вам еще один способ округления: к округляемому числу прибавляем 0.5 и отбрасываем дробную часть
|
|||
|
||||
Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Всем спасибо за ответы
![]() В заключении темы хотелось бы все-таки выяснить, так есть ли в Delphi функция, каторая выполняла бы то, что задокументировано для Round ? Т.е. функция, каторая округляла бы по общепринятым правилам, а не по каким-либо бухгалтерским или еще. Чтоб <?,5 округляло к меншему, а >=?.5 - к большему. Или все таки придется написать такую функцию самому? Santer
-------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
Alex |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4147 Регистрация: 25.3.2002 Где: Москва Репутация: 80 Всего: 162 |
Ты так и не понял проблемы. -------------------- Написать можно все - главное четко представлять, что ты хочешь получить в конце. |
|||
|
||||
Poseidon |
|
||||||||||||||||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Alex
Это действительно проблема, т.к. в книге по Delphi написано буквально следующее:
Даже в справке Delphi написано
PS. Хотелось бы все таки узнать, есть ли та функция, что округлит 3,5 к 4 ("по известным правилам"). Как видно Round не справляется. Alex, лично к тебе: В одной из других тем (не так давно) ты писал следующее:
и
Как говорится: "Модератор всегда прав" (p0s0l) Это сообщение отредактировал(а) Poseidon - 12.3.2005, 20:21 -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
||||||||||||||||
|
|||||||||||||||||
Alex |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4147 Регистрация: 25.3.2002 Где: Москва Репутация: 80 Всего: 162 |
Poseidon, я насколько понимаю, ты меня обвиняешь в том, что я тебе отвечаю не полностью на твой вопрос. Прошу заметить, что я не участвую в обсуждении этой проблемы. Я только дал ссылку на статью, о которой упомянул один из участников. Как говорится, не знаю досконально вопроса и не лезу.
-------------------- Написать можно все - главное четко представлять, что ты хочешь получить в конце. |
|||
|
||||
Alex |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4147 Регистрация: 25.3.2002 Где: Москва Репутация: 80 Всего: 162 |
Полазил я тут по сети и нашел ответ на вопрос.
-------------------- Написать можно все - главное четко представлять, что ты хочешь получить в конце. |
|||
|
||||
Петрович |
|
||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 25 Всего: 55 |
А следующее предложение в хелпе переводить не пробовал? Тогда помогу я ![]()
Если X точно посередине между двумя числами, результат будет ЧЕТНЫМ числом.
Читайте внимательнее хелп!
Если имеются ввиду школьные правила, то читай внимательнее мой пост выше -------------------- Все знать невозможно, но хочется |
||||||||
|
|||||||||
Alex |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4147 Регистрация: 25.3.2002 Где: Москва Репутация: 80 Всего: 162 |
Poseidon, если ты задаешь вопрос, и тебе отвечают, то будь любезен проверять то, что тебе предлагают, а не орать на весь форум, что тебя обидели и все такие нехорошие.
Держи свой код ![]()
-------------------- Написать можно все - главное четко представлять, что ты хочешь получить в конце. |
|||
|
||||
Poseidon |
|
||||||||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Alex
Петрович
Огромное спасибо всем кто принял участие в обсуждении этой темы!!! Отдельное спасибо Петрович и Alex. В следующий раз буду по внимательнее. -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
||||||||
|
|||||||||
amsoft |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 201 Регистрация: 17.10.2009 Где: KZ, Astana Репутация: 3 Всего: 4 |
Возвращаясь к старой теме:
Недавно тоже столкнулся с такой некорректной работой функции Round. При округлении числа, дробная часть которого = 0.5 всегда возвращает четное число, это баг с точки зрения математики (тем более каждое неправильное округление в моем случае может обойтись в реальную "копеечку"). Но разработчикам дельфей видать не знакомы правила математики ![]() Я победил это так:
ЗЫ У меня D5, может в более поздних версиях нет такого бага --------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин |
|||
|
||||
Демо |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1278 Регистрация: 3.11.2005 Репутация: 30 Всего: 50 |
amsoft,
Так что никакого глюка. В Help именно так и описано поведение Round. Это сообщение отредактировал(а) Демо - 10.12.2009, 11:44 -------------------- |
||||
|
|||||
amsoft |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 201 Регистрация: 17.10.2009 Где: KZ, Astana Репутация: 3 Всего: 4 |
Демо,
я знаю - читал уже, но меня не устраивает такой метод округления. Кстати, раз уж его называют "Banker’s Rounding", то могли бы его засунуть в функцию типа BankerRound, а Round сделали бы нормальным. Чуть модернизировал, теперь работает с отрицательными числами тоже ![]()
ЗЫ Не побоюсь этого слова Smart ![]() --------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин |
|||
|
||||
amsoft |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 201 Регистрация: 17.10.2009 Где: KZ, Astana Репутация: 3 Всего: 4 |
кстати, есть ли в делфях уже готовая подобная функция, чтобы велосипедостроительством не заниматься?
--------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин |
|||
|
||||
profesiachuvak |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 283 Регистрация: 7.11.2009 Где: Беларусь, Минск Репутация: нет Всего: 4 |
Да какой тут велосипед, ранее предлогалось сделать так
Вот и весь велосипед. Округляй с помощью trunc() и получишь нормальное математическое округление по школьным правилам. -------------------- Закон Мерфи :если есть вероятность того, что какая-нибудь неприятность может случиться, то она обязательно произойдет. |
||||
|
|||||
amsoft |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 201 Регистрация: 17.10.2009 Где: KZ, Astana Репутация: 3 Всего: 4 |
profesiachuvak,
где-то в этой теме промелькала такая мысль, почему-то не обратил на нее внимание сразу Thx --------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
profesiachuvak, а если число отрицательное?
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Демо |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1278 Регистрация: 3.11.2005 Репутация: 30 Всего: 50 |
Этот велосипед для простейших случаев.
Простой пример - 2.4(9), получающееся в процессе вычислений. -------------------- |
||||
|
|||||
Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 3 Всего: 7 |
trunc(3.9)=3, а не 4. Лучше уж frac(x)>0.5 проверять. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. ![]() Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
amsoft |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 201 Регистрация: 17.10.2009 Где: KZ, Astana Репутация: 3 Всего: 4 |
Alexeis,
немного подшаманить можно:
Добавлено через 1 минуту и 2 секунды Beltar, а прибавлять 0.5 кто будет? --------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин |
|||
|
||||
~FoX~ |
|
|||
![]() НЕ рыжий!!! ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2819 Регистрация: 8.10.2003 Где: Зеленоград Репутация: 13 Всего: 68 |
Poseidon, Лениво читать весь тред, но имел счастья сталкнутся с обратной проблемой, вобшим не суть дело... Тип Currency даст тебе то что ты хочешь поиметь...
Это сообщение отредактировал(а) ~FoX~ - 10.12.2009, 18:34 |
|||
|
||||
Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 3 Всего: 7 |
Чего прибавлять??
Или я не прав: -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. ![]() Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Можно, но тут уже добавилось ветвление и конструкция перестала быть изящной. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
amsoft |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 201 Регистрация: 17.10.2009 Где: KZ, Astana Репутация: 3 Всего: 4 |
Alexeis, ИМХО Без ветвления никуда
![]() Добавлено через 1 минуту и 17 секунд Beltar, главное результат ЗЫ мой прошлый велосипед с десятью колесами и двумя сиденьями в топку ![]() --------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 31 Всего: 88 |
Модератор: amsoft, не нужно откапывать старые темы.
-------------------- Обижено школьников: 8 |
|||
|
||||
amsoft |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 201 Регистрация: 17.10.2009 Где: KZ, Astana Репутация: 3 Всего: 4 |
bems,
я вообще хотел создать новую тему, но нашел тему с похожей проблемой и решил "добить" ее до конца, ибо это меня тоже касается. В принципе с этим вопросом разобрались. Тема может быть закрыта. --------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин |
|||
|
||||
Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 3 Всего: 7 |
Что-то я туплю.
-------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. ![]() Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 31 Всего: 88 |
amsoft, ну это так, на будущее. Если бы я увидел в этом нарушение, было бы предупреждение в личное дело. В данном случае поднятие топика оправдано, да.
-------------------- Обижено школьников: 8 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |