Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.07.18;
Скачать: [xml.tar.bz2];

Вниз

Интересная проблема с SimpleRoundTo   Найти похожие ветки 

 
Song ©   (2004-07-04 12:35) [0]

Читаем хэлп:
*************
Rounds a floating-point value to a specified digit or power of ten using asymmetric arithmetic rounding.
The following examples illustrate the use of SimpleRoundTo:
....
....
Expression Value

SimpleRoundTo(1234567, 3) 1234000
SimpleRoundTo(1.234, -2) 1.23
SimpleRoundTo(1.235, -2) 1.24
SimpleRoundTo(-1.235, -2)     -1.23
**************************

Как видно пример с 1.235 прокатывает и 1.235 округляется правильно в 1.24 согласно школьным правилам округления.
Я у себя делаю Result:=SimpleRoundTo(Result,-2); при Result равным 1.175 и получаю 1.17, а не 1.18.
ПОЧЕМУ? :)

Это предистория. Далее я написал новый проект вот так:
procedure TForm1.Button1Click(Sender: TObject);
Function Pr: Double;
Var t: Integer;
   k: Double;
Begin
Result:=4.7;
k:=0.5;
Result:=Result * k;
For t:=1 to 1 Do Result:=SimpleRoundTo(Result * 0.5,-2);
End;
begin
ShowMessage(FloatToStr(Pr));
end

Здесь работает. Но ПОЧЕМУ-ТО не работает в моей программе.
Уже отчался найти багу, поэтому вывожу всю функцию.
Function NewK(Format,n: String): Double;
{ Функция вычисления коээфициента увелечения многополосных газет
 по новому формату }
Var t,z,Polosn: Integer;
   k: Double;
Begin
Result:=-1;
try
 Polosn:=StrToInt(n);
except
 MessageDlg("Неизвестная полосность. Коэффициент увеличения массы многополосных газет " +
   "не может быть определён.",mtError,[mbOk],0);
 Exit;
end;
 { Высчитываем коээфициент увеличения массы многополосных газет
   исходя из коэффициента для базового формата А2 }
Case Polosn OF
 0..5: Result:=1;
 6..13: Result:=1.2;
 14..29: Result:=1.8;
 30..31: Result:=3;
 32..41: Begin
          Result:=3.5;
          IF Polosn > 32 then For t:=33 to Polosn Do
           IF not Odd(t) then Result:=Result + 0.2;
         End; {IF}
  { Для полосности больше 42 }
 else Begin
       Result:=4.4;
       IF Polosn > 42 then For t:=43 to Polosn Do
        IF not Odd(t) then Result:=Result + 0.1;
      End; {else}
End; {Case}
 { Получаем текущий формат }
try
 z:=StrToInt(Format);
except
 MessageDlg("Неизвестный формат (" + Format + "). Коэффициент увеличения массы " +
   "многополосных газет будет взят как для формата А2.",mtError,[mbOk],0);
 Exit;
end;
 { Если формат больше А2, то корректируем его }
IF z > 2 then
 Begin
  Case Polosn OF
   0..5: k:=0.6;
   6..29: k:=0.7;
   30..33: k:=0.52;
   else k:=0.5;
  End; {Case}
   { Определяем базовый коэффицицент для формата А3 }
  Result:=Result * k; // ТА САМАЯ Строчка :))
   { Корректируем для более малых форматов, начиная с А4 }
  IF z > 3 then For t:=4 to z Do Result:=SimpleRoundTo(Result * 0.5,-2);
 End; {IF}
End;


Вызоваем её с параметрами NewK("4","48")

После строчки Result:=Result * k; имеем в Result 2.35
Далее умножаем 2.35 * 0.5 и получаем 1.175 и округляем до двух знаков. Должно получаться 1.18, а получается в Result 1.17 :(


 
Alx2 ©   (2004-07-04 12:38) [1]

>Song ©   (04.07.04 12:35)  
Внимательно пост не читал. Но флаг округления в сопроцессоре учитывается?


 
Alx2 ©   (2004-07-04 12:42) [2]

Имею в виду x87 FPU Control Word биты 10 и 11


 
Song ©   (2004-07-04 12:49) [3]

Я его нигде не изменял.
Есть проект 1 и проект 2.
В проекте 1 не работает
В проекте 2 работает. :)
В проекте 1 никаких Set8087CW или SetRoundMode не используется. Проект 2 создан как обычно из ИДЕ :)


 
Song ©   (2004-07-04 12:51) [4]

Даже если перенести всю эту функцию из нерабочего проекта 1 в рабочий проект 2, то она всё-равно не работает. Вообщем, имеем интересную ситуацию: две одинаковых по смыслу и по используемому алгоритму функции, но одна работает, вторая - нет. :)


 
Alx2 ©   (2004-07-04 12:53) [5]

А если его все-таки посмотреть и сравнить? Мало ли кто его передернуть мог...


 
Song ©   (2004-07-04 12:55) [6]

Ну проект 1 - это я сильно сказал. Под проектом 1 я имею ввиду ту процедурку Procedure Button1Click, которуя я написал для теста. Она работает. А NewK() - нет.
Когда я переношу NewK в проект с Button1Click, тоже самое: последняя работает, NewK - нет.


 
Alx2 ©   (2004-07-04 13:10) [7]

Все-таки я бы сверил флаг


 
Song ©   (2004-07-04 19:02) [8]

Вопрос решил.
Оказалось дробные числа каверзные :)
В переменной было
1.17499999999999
поэтому когда округляешь по 2-му знаку, он совершенно правильно округляет в 1.17
поэтому нужно сначала по 3-ему, а потому по 2-му ))


 
Anatoly Podgoretsky ©   (2004-07-04 19:07) [9]

Song ©   (04.07.04 19:02) [8]
Это только для случая если 1.17499999999999 неверное из за относительной точности, а если число реальное, то такое округление будет неверным, вместо 1,17 будет 1,18


 
Anatoly Podgoretsky ©   (2004-07-04 19:12) [10]

Song ©   (04.07.04 19:02) [8]
Если просматривать в отладчике, то надо принудительно указывать тип Extended ина отображение урезано до 15 символов



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.07.18;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.046 c
1-1088842326
clampo
2004-07-03 12:12
2004.07.18
самонахождение файлов *.bmp


9-1080845721
Hecz
2004-04-01 22:55
2004.07.18
Использование физики


8-1082888994
gyry
2004-04-25 14:29
2004.07.18
Своя иконка


1-1088948357
чудак
2004-07-04 17:39
2004.07.18
вопрос про PageControl


14-1088350057
Sir John
2004-06-27 19:27
2004.07.18
интернет от Stream.ru





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский