Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Загадка / 25 сообщений из 32, страница 1 из 2
25.11.2017, 16:09:25
    #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
25.11.2017, 16:21:53
    #39559427
alekcvp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загадка
asviridenkov,

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


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

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

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

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

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

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

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

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

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

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

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

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


Типы чего? И как это влияет?
...
Рейтинг: 0 / 0
25.11.2017, 20:23:15
    #39559488
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загадка
asviridenkovИ как это влияет?очевидно, на выбор перегруженной функции
Код: pascal
1.
2.
    function SplitRect(SplitType: TSplitRectType; Size: Integer): TRect; overload;
    function SplitRect(SplitType: TSplitRectType; Percent: Double): TRect; overload;
...
Рейтинг: 0 / 0
25.11.2017, 20:25:54
    #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
25.11.2017, 20:28:05
    #39559490
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загадка
asviridenkovПриз в студию!вероятно, я просто первый, кто не поленился найти объявления этих функций
...
Рейтинг: 0 / 0
25.11.2017, 20:38:17
    #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
25.11.2017, 21:01:29
    #39559500
asviridenkov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загадка
fd00ch,

так cValue то у тебя не константа, по факту она переменная
...
Рейтинг: 0 / 0
25.11.2017, 21:12:39
    #39559505
fd00ch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загадка
asviridenkov, по факту у нее точно задан тип)) в "краткой" записи появляется возможность порассуждать, имеет ли компилятор право принять ее за Double
...
Рейтинг: 0 / 0
25.11.2017, 21:16:32
    #39559506
Гаджимурадов Рустам
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загадка
asviridenkovНо не кажется ли уважаемым донам, что сама ситуация, когда выбор функции меняется в зависимости от того что находится внутри round, не вполне здоровая?Нет, не кажется.
...
Рейтинг: 0 / 0
25.11.2017, 21:17:07
    #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
25.11.2017, 21:19:23
    #39559508
asviridenkov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Загадка
Гаджимурадов РустамasviridenkovНо не кажется ли уважаемым донам, что сама ситуация, когда выбор функции меняется в зависимости от того что находится внутри round, не вполне здоровая?Нет, не кажется.

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

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


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