![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| Burka |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 429 Регистрация: 11.5.2007 Репутация: нет Всего: 2 |
Давно бьюсь над процедурой округления, которая будет правильно округлять все числа, по школьному правилу.
Сейчас использую такую процедуру.
Не давно нашел такой баг в ней при округлении допустим числа -12.15 до десятых получаем -12.2 (правильно) но округляя -22.15 получаем -22.1 (не правильно) Подскажите есть ли стабильные процедуры для этого или может что в моей исправить -------------------- Великие умы обсуждают идеи; средние умы обсуждают события; мелкие умы обсуждают людей. |
|||
|
||||
| XperT |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 269 Регистрация: 19.8.2006 Репутация: 2 Всего: 4 |
Посмотри в сторону Math.SimpleRoundTo
|
|||
|
||||
| Burka |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 429 Регистрация: 11.5.2007 Репутация: нет Всего: 2 |
пока округляю с помощью FormatFloat и вроде норм
-------------------- Великие умы обсуждают идеи; средние умы обсуждают события; мелкие умы обсуждают людей. |
|||
|
||||
| shmelina |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 5.6.2009 Репутация: нет Всего: нет |
SimpleRoundTo тоже неправильно округляет. Сам проверил.
Вообще с округлением не все так просто. Я когда прочитал эту статью, мне плохо стало: Загадки округления. http://www.delphikingdom.com/asp/viewitem.asp?catalogID=1217 Я пока остановился на этом способе: Trunc(Value * 100 + 0.5) / 100 |
|||
|
||||
| Burka |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 429 Регистрация: 11.5.2007 Репутация: нет Всего: 2 |
shmelina, спасибо тоже попробовал твой метод, отрицательные числа он не правильно округляет я немного доработал) лишь бы работало)
А вообще надо найти или написать уже корректную процедурку -------------------- Великие умы обсуждают идеи; средние умы обсуждают события; мелкие умы обсуждают людей. |
|||
|
||||
| shmelina |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 5.6.2009 Репутация: нет Всего: нет |
Число 1.15 округляется до 1.1
|
|||
|
||||
| shmelina |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 5.6.2009 Репутация: нет Всего: нет |
Странно. Поднял свои исследования на тему округления. Даже тогда написал специальную программу, которая округляет разными способами. И точно помню, что пришел к выводу, что есть проблемы с функцией SimpleRoundTo. Проверял на D2009. Но сейчас не могу вспомнить какие именно.
Сейчас все пробую и вроде все правильно работает. Единственное, что нашел, что в D7 реализация функции SimpleRoundTo на отрицательных числах будет ошибочная:
В более поздних версиях (турбо (2006), 2007) сделали уже правильно:
Если смотреть на исследования в статье, то такое ощущение, что в функции SimpleRoundTo не было "+ 0.5". Может в патче потом добавили? Сейчас не важно. Пока такой вывод: функция SimpleRoundTo работает правильно, если она такая:
Верно? |
||||||
|
|||||||
| shmelina |
|
||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 5.6.2009 Репутация: нет Всего: нет |
Так. Снова погрузился в проблемы округления. Вот что выяснилось на этот раз: Результаты округления зависят
1. от типа данных переменной, которую округляем. 2. от типа данных параметров функции округления SimpleRoundTo. В Delphi 2007 функция объявлена так: function SimpleRoundTo(const AValue: Double; const ADigit: TRoundToRange = -2): Double; В Delphi 2010 функция объявлена так: function SimpleRoundTo(const AValue: Extended; const ADigit: TRoundToRange = -2): Extended; Вроде бы тип данных сменился и только! Но как оказалось это влияет на результат - смотря что вы в нее передадите. И так я протестировал две реализации функции SimpleRoundTo (Double и Extended) и округление прямо в коде: Trunc(Value * 10 + 0.5) / 10. Тестировал на Delphi 2010. Три разных типа данных: Currenty, Double и Extended. Округлял число 1.15 до одного знака после запятой. Вот что получилось:
А вот с числом 1,25
С отрицательными числами такая же картина. Вывод: 1. Переменную типа Double с помощью функции SimpleRoundTo корректно округлить нельзя. 2. Переменную любого типа с помощью функции SimpleRoundTo, где параметр передается как Double, корректно округлить нельзя. Короткий вывод: Не используйте Double в округлениях Вот код, которым я все это проверил. Положите на форму StringGrid и дайте ему имя sg.
Не судите строго, если я где-то ошибся в своих исследованиях. Поправьте. |
||||||
|
|||||||
| Burka |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 429 Регистрация: 11.5.2007 Репутация: нет Всего: 2 |
Я думаю логичнее было бы не использовать SimpleRoundTO ^^ и вообще лучше ничего не использовать из стандартных процедур для округления при серъезных подсчетах где важны погрешности. А вообще я сейчас пользуюсь этим, и радуюсь) Юзеры не приходили пока с жалобами)
вообще она возращала строковую но мне не удобно так) Это сообщение отредактировал(а) Burka - 4.3.2010, 15:17 -------------------- Великие умы обсуждают идеи; средние умы обсуждают события; мелкие умы обсуждают людей. |
||||
|
|||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |