Форум: "Основная";
Текущий архив: 2003.11.27;
Скачать: [xml.tar.bz2];
ВнизКак округлить дробное число с 3-х занков до 2-х после запятой? Найти похожие ветки
← →
Developerr (2003-11-16 19:58) [0]Извиняюсь за не очень умный вопрос, но, что вылетело...
Подскажите, пожалуйста, как округлить в Delphi дробное число с 3-х занков до 2-х после запятой? Например, 2958,375 до 2958,38.
Спасибо.
← →
Cr@sh (2003-11-16 19:59) [1]uses Math
RoundTo();
← →
Developerr (2003-11-16 20:14) [2]Спасибо, но эта функция по-моему с глюками. Как объяснить, что она округляет число 2958,375 до 2958,37, а не 2958,38? А число 1.245 округляет нормально. Хотя, если добавить впереди еще единичку 11.245 получится 11.24 ???
Может есть какой-то секрет?
Спасибо.
← →
Думкин (2003-11-16 20:18) [3]Секрет этот тут каждый день раскрывается.
Нужно только взглянуть на код этой функции, а потом в хелпе прочитать про Round, только до конца.
Вот и весь секрет.
← →
Anatoly Podgoretsky (2003-11-16 20:23) [4]У тебя не это число, тебе только кажется
← →
Лена (2003-11-16 20:32) [5]нужно число открыть как стринг и срезать последний символ
так пойдет ?
← →
Developerr (2003-11-16 20:45) [6]Expression Value
RoundTo(1234567, 3) 1234000
RoundTo(1.234, -2) 1.23
RoundTo(1.235, -2) 1.24
RoundTo(1.245, -2) 1.24
Note: The behavior of RoundTo can be affected by the Set8087CW procedure or SetRoundMode function.
Хрень какая-то.
Кстати, RoundTo(1.245, -2)=1.25, а не 1.24. Не глюк? Глюк. Вы попробуйте эти примеры...
> Anatoly Podgoretsky
> У тебя не это число, тебе только кажется
Самому хоть понятна эта формулировка?
Кто-нибудь может дать дельный совет, а лучше пример?
← →
Иван Шихалев (2003-11-16 20:50) [7]> Как объяснить, что она округляет число 2958,375
> до 2958,37, а не 2958,38?
2958.375 округляется до 2958.38, см. Help
← →
Лена (2003-11-16 20:53) [8]Developerr >
пример с обризанием последнего символа выложить ?
← →
Alexious (2003-11-16 20:55) [9]n:=2958.375;
n:=Round(n*100)/10;
:)))
← →
Alexious (2003-11-16 20:58) [10]
n:=2958.375;
n:=Round(n*100)/10;
:))
← →
sniknik (2003-11-16 21:02) [11]Developerr © (16.11.03 20:45) [6]
бугалтерское округление, слышал о таком? более правильное при больших последовательностях округляемых чисел (и суммировании) чем школьное математическое. т.что это не глюк.
> Кто-нибудь может дать дельный совет, а лучше пример?
а совет ты сам сюда привел, только не обратил внимания
> Note: The behavior of RoundTo can be affected by the Set8087CW procedure or SetRoundMode function.
т.е. вызов SetRoundMode(rmNearest); перед RoundTo решит твою проблему(??).
кстати у меня по умолчанию так стоит (зависит от конкретного сопроцессора?)
← →
Alexious (2003-11-16 21:03) [12]
n:=2958.375;
n:=Round(n*100)/10;
:))
← →
Anatoly Podgoretsky (2003-11-16 21:07) [13]Developerr © (16.11.03 20:45) [6]
Очень даже понятна, а тебе, раз у тебя это вызвало удивление.
← →
Developerr (2003-11-16 21:08) [14]
> Лена
Мне нужно не просто обрезать, а округлить. Если вы это имели ввиду, тогда выложите, пожалуйста.
> Иван Шихалев ©
Где смотреть в Help"e?
Я пробую так:ShowMessage(FloatToStr(RoundTo(2958,375)));
или так:
n:=RoundTo(2958,375);
ShowMessage(FloatToStr(n));
Получается 2958,37 и все тут.
← →
Zmei (2003-11-16 21:12) [15]Так попробуй ShowMessage(floattostr(Round(3958.37*100)/10));
← →
Developerr (2003-11-16 21:13) [16]
> Anatoly Podgoretsky
Мне нет!!!
> Alexious ©
> n:=2958.375;
> n:=Round(n*100)/10;
> :))
Это что? Тут совсем не то.
← →
Developerr (2003-11-16 21:17) [17]
> Zmei
Причем тут это
> Так попробуй ShowMessage(floattostr(Round(3958.37*100)/10));
Мне нужно из 2958.375 получить 2958.38.
← →
Фдучшщгы (2003-11-16 21:29) [18]>Developerr © (16.11.03 21:17) [17]
Ну и че эта штука же работает . ты хоть пробовал
Делай так
ShowMessage(floattostr((Round(3958.375*100))/10));
и все будет ништяк
← →
Developerr (2003-11-16 21:34) [19]
> Фдучшщгы
Вы что издеваетесь? Вы пробовали использовать то что написали???
В результате получается - 39583,8
> sniknik ©
Пробовал писать так:
SetRoundMode(rmNearest);
ShowMessage(FloatToStr(RoundTo(2958,375)));
Все одно - 2958,37
:-(((((
← →
Alexious (2003-11-16 21:48) [20]Ну подправил бы. Ошибся
ShowMessage(floattostr((Round(3958.375*100))/100));
← →
Developerr (2003-11-16 21:56) [21]
> Alexious ©
Спасибо. Получилось.
← →
sniknik (2003-11-16 22:28) [22]Developerr © (16.11.03 21:34) [19]
> Пробовал писать так:
> SetRoundMode(rmNearest);
> ShowMessage(FloatToStr(RoundTo(2958,375)));
> Все одно - 2958,37
там еще 3 параметра осталось попробуи их чтоли.
но вообще SetRoundMode както там странно вычисляет (и видать неправильно), маленькие числа правильно округляет а вот 2958,375 какоето "волшебное" ;о)).
установи напрямую для гарантии
Set8087CW($1B72);
ShowMessage(FloatToStr(RoundTo(2958,375)));
у меня срабатывает.
← →
Иван Шихалев (2003-11-16 22:55) [23]> 2958,375 какоето "волшебное" ;о)).
Гм... Т.е. округялет и не к ближайшему и не к четному? Оригинально. Delphi нет, проверить не могу... Если это число действительно такое волшебное, то дело во внутреннем представлении... Может помочь замена типа, особенно - в сторону большей точности.
← →
sniknik (2003-11-16 23:07) [24]> Может помочь замена типа, особенно - в сторону большей точности.
если дело было в разрядности сетки(т.е. представление не 2958,375 а 2958,374915.... ну как обычно) то по идее и Set8087CW($1B72); не помогло бы (даже по школьному тогда былобы ...2958,37)
а может это учитывается в параметре $1B72 а тот что вычисляется в SetRoundMode этого не учитывает (ведь в итого тоже Set8087CW вызывается только с другим параметром).
← →
Иван Шихалев (2003-11-16 23:19) [25]> не помогло бы
Не факт. Все эти фокусы с плавающей точкой - тот еще лабиринт. Доки жаль под рукой нет по режимам сопроцессора... Кроме того, если число не вводится ручками, а вычисляется, то одна и та же операция может возвращать как 0.24992, так и 0.25001 (цифры взяты от балды).
← →
Иван Шихалев (2003-11-16 23:19) [26]В смысле - одна операция при разной размерности.
← →
Думкин (2003-11-17 05:37) [27]> [20] Alexious © (16.11.03 21:48)
Ровно так и работает RoundTo. :-(
> [25] Иван Шихалев © (16.11.03 23:19)
Скорее всего дело в этом. Поэтому и разница в
> А число 1.245 округляет нормально. Хотя, если добавить впереди
> еще единичку 11.245 получится 11.24 ???
все-такки плавающая точка - она и есть плавающая точка.
← →
sniknik (2003-11-17 08:14) [28]Иван Шихалев © (16.11.03 23:19) [25]
Думкин © (17.11.03 05:37) [27]
доки нет да жаль.
а зависит ли от числа? скорее всего режим неправильный какойто устанавливается
посмотрел
в SetRoundMode вычисляется и устанавливается Set8087CW( $31С4), чего этим делается и этого ли добится хотели?, чего в хелпе
rmNearest Rounds to the closest value.
ведь с ручным вводом режима Set8087CW($1B72) работает правильно.
← →
BlackTiger (2003-11-17 10:49) [29]2 sniknik: бугалтерское округление, слышал о таком
нет такого округления, есть банковское, т.е. округление до ближайшего четного. Насколько я знаю - почти нигде не используется, т.к. очень усложняет расчеты.
Блин, народ! Че флейм разводить по такому дурацкому вопросу? Вы в школе нормально учились?
Берем 33.12 482, а точнее 33.12 482).
Округление до 2х знаков даст 33.12, так как 482 < 500 (точнее 4 < 5).
Огругление до 3х знаков даст 33.125, так как 82 > 50 (точнее 8 > 5).
Вот и все округление. Все остальное - от лукавого!
← →
Anatoly Podgoretsky (2003-11-17 11:15) [30]BlackTiger © (17.11.03 10:49) [29]
Насчет нигде, ты очень, очень преувеличил.
И на школу не надо бочку катить.
← →
Семен Сорокин (2003-11-17 11:18) [31]2All
Каждый раз одно и тоже.
ЗЫ
Если один раз - случайность, два - совпадение, а три - диагноз. :)
(С)
← →
Думкин (2003-11-17 11:32) [32]
> [30] Anatoly Podgoretsky © (17.11.03 11:15)
Фууу, а я думал опять кровью завоняло, а стоит ли?
← →
Anatoly Podgoretsky (2003-11-17 11:36) [33]Пусть живет.
← →
Silver Alex (2003-11-17 11:40) [34]
> BlackTiger © (17.11.03 10:49) [29]
> 2 sniknik: бугалтерское округление, слышал о таком
> нет такого округления, есть банковское, т.е. округление
> до ближайшего четного. Насколько я знаю - почти нигде не
> используется, т.к. очень усложняет расчеты.
ну попробуй для эксперимента
Round(12,5) равно 12
а Round(13,5) равно 14
то же и с RoundTo
страно правда? но это и есть бугалтерское округление о котором сразу сказал sniknik ©
← →
Anatoly Podgoretsky (2003-11-17 11:46) [35]Silver Alex © (17.11.03 11:40) [34]
Не странно, а вполне нормально, а еще более нормально использовать то округление, которое нужно для задачи, а их не одно и не два.
← →
Developerr (2003-11-17 12:01) [36]
> sniknik ©
> ведь с ручным вводом режима Set8087CW($1B72) работает правильно.
Для этого случая правильно. А если взять число, скажем 2958,30 и посмотри, что получится. А получится 2958,31. Раззве это правильно? На мой взгляд самое правильное решение:
> ShowMessage(floattostr((Round(3958.375*100))/100));
Работае четко и во всех случаях.
← →
sniknik (2003-11-17 12:14) [37]какая разница как назвать. тут уже дело в другом
читаем хелп
у раундов
Note: The behavior of Round can be affected by the Set8087CW procedure or SetRoundMode function.
т.е. или то или то.
у SetRoundMode
rmNearest Rounds to the closest value.
т.е. к ближайшему значению.
а на практике видим другое (хотя правильного поведения добится не проблема) но почему написаное в хелпе не срабатывает (глюк дельфей? или неправильный перевод?)
вот что странно. а не уже действительно надоевшее обсуждение одного и тогоже (сктати замедтье и отмазки тоже похожие, и уже надоевшие)
> BlackTiger © (17.11.03 10:49) [29]
> Насколько я знаю - почти нигде не используется, т.к. очень усложняет расчеты.
сказал бы ты это нашему бугалтеру, она бы тебя порвала как бобик жучку. ;о))
кроме шуток у нее и с этим по округлениям до ста руб. набегает (плюса а для нее это недостача) с математическим раз в 20 возрастет.
← →
sniknik (2003-11-17 12:21) [38]Developerr © (17.11.03 12:01) [36]
нда... уж. действительно.
срочно нужна дока по режимам сопроцессора!! :о))
← →
sniknik (2003-11-17 12:37) [39]Developerr © (17.11.03 12:01) [36]
> Работае четко и во всех случаях.
во всех ли?
посмотри на функцию RoundTo, ничего знакомого не видиш? только тут обратные операции LFactor получается 0.01
function RoundTo(const AValue: Double; const ADigit: TRoundToRange): Double;
var
LFactor: Double;
begin
LFactor := IntPower(10, ADigit);
Result := Round(AValue / LFactor) * LFactor;
end;
деление на 0.01 = умножению на 100 и наоборот.
кстати похоже в этом и есть ошибка дельфей (алгоритм), они работают с дробными числами, плодят т.к. сказать ошибку, ведь чем меньше числа тем больше погрешностей в разрядной сетке можно словить, не. а установка режима вовсе не причем. (?)
← →
Anatoly Podgoretsky (2003-11-17 12:40) [40]sniknik © (17.11.03 12:21) [38]
На сайте Интела
sniknik © (17.11.03 12:37) [39]
Тут происходит много преобразований, и на каждом возможна ошибка представления.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2003.11.27;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.012 c