powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Загадка
25 сообщений из 32, страница 1 из 2
Загадка
    #39559421
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пишем так
Код: pascal
1.
2.
3.
          DrawThemeBackground(Theme, Canvas.Handle, TTP_BALLOONSTEM,
            TTBSS_POINTINGDOWNLEFTWALL, SplitRect(ClientRect, srBottom,
             cBalloonStemHeight + round(11 * Screen.PixelsPerInch / 96)), @MeasureRect)



работает неправильно.
Пишем так

Код: pascal
1.
2.
3.
          DrawThemeBackground(Theme, Canvas.Handle, TTP_BALLOONSTEM,
            TTBSS_POINTINGDOWNLEFTWALL, SplitRect(ClientRect, srBottom,
             cBalloonStemHeight + round(11 * 96 / 96)), @MeasureRect)


Работает правильно. При этом Screen.PixelsPerInch в отладчике = 96.
Ок, пишем так:

Код: pascal
1.
2.
3.
4.
5.
6.
var n: integer;
...
 n := 96;
          DrawThemeBackground(Theme, Canvas.Handle, TTP_BALLOONSTEM,
            TTBSS_POINTINGDOWNLEFTWALL, SplitRect(ClientRect, srBottom,
             cBalloonStemHeight + round(11 * n / 96)), @MeasureRect)


И снова работает неправильно.
...
Рейтинг: 0 / 0
Загадка
    #39559427
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkov,

Если посмотреть в исходники, то там AFAIR используется
Код: pascal
1.
MulDiv(11, Screen.PixelsPerInch, 96)


Видимо, не просто так.
...
Рейтинг: 0 / 0
Загадка
    #39559430
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkov,

Подозреваю, это из-за того что 11 * 96 / 96 - константа, вычисляемая компилятором, а всё остальное выражение, которое вычисляется в рантайм с какой-то точностью (не знаю к чему он по-умолчанию приводит - Real/Single?). Вот эта точность + Round и приводит к неожиданным результатам.
...
Рейтинг: 0 / 0
Загадка
    #39559431
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpasviridenkov,

Подозреваю, это из-за того что 11 * 96 / 96 - константа, вычисляемая компилятором, а всё остальное выражение, которое вычисляется в рантайм с какой-то точностью (не знаю к чему он по-умолчанию приводит - Real/Single?). Вот эта точность + Round и приводит к неожиданным результатам.

Так там вокруг round стоит, так что точность вычисления не должна влиять.
...
Рейтинг: 0 / 0
Загадка
    #39559434
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovТак там вокруг round стоит, так что точность вычисления не должна влиять.
А отладчик что показывает на выражении round(11 * Screen.PixelsPerInch / 96) ?
...
Рейтинг: 0 / 0
Загадка
    #39559439
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

11 показывает
...
Рейтинг: 0 / 0
Загадка
    #39559440
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkov,

Тогда что именно не работает?
...
Рейтинг: 0 / 0
Загадка
    #39559472
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpasviridenkov,

Тогда что именно не работает?

Этот код работает совершенно по-разному, в первом случае стрелка у хинта есть, во втором нет, хотя казалось бы результат должен быть идентичным.
...
Рейтинг: 0 / 0
Загадка
    #39559478
Freedoom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
asviridenkovЭтот код работает совершенно по-разному, в первом случае стрелка у хинта есть, во втором нет, хотя казалось бы результат должен быть идентичным.
Во втором варианте round - константа, в первом и третьем - вычисление с приведением различных типов. Выделите отдельной строкой SplitRect и посмотрите в отладчике (окно assembler) какой код генерируется компилятором. Думаю после этого вопросов не останется.
...
Рейтинг: 0 / 0
Загадка
    #39559480
Сергей N
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
При использовании round имейте в виду, что эта функция производит округление по банковским правилам, где точная половина значения вызывает округление к четному числу (2.5 -> 2, 3.5 -> 4). Функция MulDiv работает с целыми числами и всегда округляет до ближайшего целого (2.5 -> 3, 3.5 -> 4).
...
Рейтинг: 0 / 0
Загадка
    #39559483
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FreedoomВо втором варианте round - константа, в первом и третьем - вычисление с приведением различных типов. Выделите отдельной строкой SplitRect и посмотрите в отладчике (окно assembler) какой код генерируется компилятором. Думаю после этого вопросов не останется.

Уже теплее)) А не глядя в отладчик можете угадать причину?
...
Рейтинг: 0 / 0
Загадка
    #39559484
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей NПри использовании round имейте в виду, что эта функция производит округление по банковским правилам, где точная половина значения вызывает округление к четному числу (2.5 -> 2, 3.5 -> 4). Функция MulDiv работает с целыми числами и всегда округляет до ближайшего целого (2.5 -> 3, 3.5 -> 4).

Тем не менее, в обоих случаях round возвращает ровно 11. Так что дело не в округлении.
...
Рейтинг: 0 / 0
Загадка
    #39559486
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkov> А не глядя в отладчик можете угадать причину?

Типы разные что ли?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Загадка
    #39559487
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустамasviridenkov> А не глядя в отладчик можете угадать причину?

Типы разные что ли?


Типы чего? И как это влияет?
...
Рейтинг: 0 / 0
Загадка
    #39559488
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovИ как это влияет?очевидно, на выбор перегруженной функции
Код: pascal
1.
2.
    function SplitRect(SplitType: TSplitRectType; Size: Integer): TRect; overload;
    function SplitRect(SplitType: TSplitRectType; Percent: Double): TRect; overload;
...
Рейтинг: 0 / 0
Загадка
    #39559489
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fd00chasviridenkovИ как это влияет?очевидно, на выбор перегруженной функции
Код: pascal
1.
2.
    function SplitRect(SplitType: TSplitRectType; Size: Integer): TRect; overload;
    function SplitRect(SplitType: TSplitRectType; Percent: Double): TRect; overload;



Приз в студию!
Но не кажется ли уважаемым донам, что сама ситуация, когда выбор функции меняется в зависимости от того что находится внутри round, не вполне здоровая?
...
Рейтинг: 0 / 0
Загадка
    #39559490
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovПриз в студию!вероятно, я просто первый, кто не поленился найти объявления этих функций
...
Рейтинг: 0 / 0
Загадка
    #39559493
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovНо не кажется ли уважаемым донам, что сама ситуация, когда выбор функции меняется в зависимости от того что находится внутри round, не вполне здоровая?вообще, на баг похоже. интересно, что на Seattle я в случае сложения с константой так и не смог добиться вызов integer-варианта вообще а вот без константы начитается веселье, как и у тебя в старт-посте
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
program Project1;

uses
 SysUtils,
 Forms   ,
 Dialogs ;

procedure Test(Value: Integer); overload;
 begin
  ShowMessage('int')
 end;

procedure Test(Value: Double); overload;
 begin
  ShowMessage('dbl')
 end;

const
 cValue: Integer = 123;
begin
  Test(cValue + Round(11 * Screen.PixelsPerInch / 96));
  Test(cValue + Round(11 * 96 / 96));

  Test(Round(11 * Screen.PixelsPerInch / 96));
  Test(Round(11 * 96 / 96));
end.
...
Рейтинг: 0 / 0
Загадка
    #39559500
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fd00ch,

так cValue то у тебя не константа, по факту она переменная
...
Рейтинг: 0 / 0
Загадка
    #39559505
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkov, по факту у нее точно задан тип)) в "краткой" записи появляется возможность порассуждать, имеет ли компилятор право принять ее за Double
...
Рейтинг: 0 / 0
Загадка
    #39559506
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovНо не кажется ли уважаемым донам, что сама ситуация, когда выбор функции меняется в зависимости от того что находится внутри round, не вполне здоровая?Нет, не кажется.
...
Рейтинг: 0 / 0
Загадка
    #39559507
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно немного помочь компилятору, будет нормально:
Код: pascal
1.
2.
3.
4.
5.
 Test(Integer(cValue + Round(11 * Screen.PixelsPerInch / 96)));
 Test(Integer(cValue + Round(11 * 96 / 96)));

 Test(Integer(Round(11 * Screen.PixelsPerInch / 96)));
 Test(Integer(Round(11 * 96 / 96)));


Косячок, конечно:
Код: pascal
1.
2.
function SplitRect(SplitType: TSplitRectType; Size: Integer): TRect; overload;
function SplitRect(SplitType: TSplitRectType; Percent: Double): TRect; overload;
...
Рейтинг: 0 / 0
Загадка
    #39559508
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамasviridenkovНо не кажется ли уважаемым донам, что сама ситуация, когда выбор функции меняется в зависимости от того что находится внутри round, не вполне здоровая?Нет, не кажется.

Ну, разверни свою мысль. То есть тебя устраивает, что ты должен точно следить, что будет внутри round, константа или значение, несмотря на то, что round то нифига не overloaded и на то что вовне ее, параметр влиять никак не должен.
...
Рейтинг: 0 / 0
Загадка
    #39559511
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,

с помощью то все понятно, более того я бы "понял и простил" если бы в обоих случаях вызывался double вариант. Но вот то, что вызовы получаются разные, на мой взгляд недопустимо.
...
Рейтинг: 0 / 0
Загадка
    #39559514
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkov... round то нифига не overloaded и на то что вовне ее, параметр влиять никак не должен.
А ROUND() - это настоящая функция или тоже из "чЮдес Delphi"?
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Загадка
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]