powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Загадка
32 сообщений из 32, показаны все 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
Загадка
    #39559515
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДasviridenkov... round то нифига не overloaded и на то что вовне ее, параметр влиять никак не должен.
А ROUND() - это настоящая функция или тоже из "чЮдес Delphi"?

Из чудес
...
Рейтинг: 0 / 0
Загадка
    #39559516
fd00ch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovround то нифига не overloaded и на то что вовне ее, параметр влиять никак не должен.Round возвращает Int64, его в Integer не запихнуть, да компилятор и не пытается - пихает в Double. а в случае констант внутри Round вычисляет выражение на этапе компиляции, получает "короткий" Int64 и лепит из него Integer. по факту - уже и не косяк ¯\_(ツ)_/¯
...
Рейтинг: 0 / 0
Загадка
    #39559517
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkov> round то нифига не overloaded

Я бы не был в этом так уверен. :)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Загадка
    #39559518
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asviridenkovчччДпропущено...

А ROUND() - это настоящая функция или тоже из "чЮдес Delphi"?

Из чудес
Да, всего лишь возвращает "ближайшее значение": http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Delphi_Intrinsic_Routines

А уж какой тип - ну, извините, так вышло...
...
Рейтинг: 0 / 0
Загадка
    #39559520
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вернее, так: "Возвращает значение X, округленное до ближайшего целого числа."
Никто не обещал никакого преобразования типа...
...
Рейтинг: 0 / 0
Загадка
    #39559523
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не знал, что они и задокументировали так бездарно. :)
А вообще, зачем гадать - можно же проверить через
TypeOf, VarTypeOf etc. Ну и от версии зависит, наверное.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Загадка
    #39559540
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fd00chasviridenkovround то нифига не overloaded и на то что вовне ее, параметр влиять никак не должен.Round возвращает Int64, его в Integer не запихнуть, да компилятор и не пытается - пихает в Double. а в случае констант внутри Round вычисляет выражение на этапе компиляции, получает "короткий" Int64 и лепит из него Integer. по факту - уже и не косяк ¯\_(ツ)_/¯
Да.

Если к набору overload - процедур
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
procedure Test(Value: Integer); overload;
 begin
  ShowMessage('int')
 end;

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


добавить прцедуру
Код: pascal
1.
2.
3.
4.
procedure Test(Value: Int64); overload;
 begin
  ShowMessage('Int64')
 end;


- то вроде все и хорошо.

"Искусственный интеллект или автоматическое приведение типов против полиморфизма", однако.
...
Рейтинг: 0 / 0
32 сообщений из 32, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Загадка
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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