Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.008 c
14-90091
vuk
2003-11-04 14:04
2003.11.27
Получите! Распишитесь!


8-89999
antonyan
2003-08-01 11:42
2003.11.27
Вставка из буфера изображения формы


3-89765
Zanik
2003-11-07 15:23
2003.11.27
Access violation в TWebModule


1-89962
romeo
2003-11-13 22:42
2003.11.27
Не хватает памяти для печати (или у меня мозгов? :-)


1-89834
Артем
2003-11-16 11:44
2003.11.27
Сохранение переменной внутри программы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский