powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / арифметика в FPC - cast Integer to Int64
25 сообщений из 31, страница 1 из 2
арифметика в FPC - cast Integer to Int64
    #39474303
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Столкнулся с проблемой (видимо из-за незнания/непонимания).

FPC 3.0.0
компилю с ключами -TWin32 -Mobjfpc

Есть такая функция:
Код: pascal
1.
2.
3.
4.
function MakeFullNumber( nSerial, nNumber: Integer ): Int64;
begin
  Result := Int64( nSerial ) * $FFFFFFFF + nNumber;
end;  



На делфи
Код: pascal
1.
ShowMessage( IntToStr( MakeFullNumber( 200210, 1 ) ) );


выдает "859895402131951" - это правильно, калькулятор подтверждает.

FPC же упорно выдает какое-то странное число "-859886812597777", даже если сделать
Код: pascal
1.
Result := Int64( Int64( Int64( nSerial ) * Int64( $FFFFFFFF ) ) + Int64( nNumber ) );



Единственное, что помогает, это переделать функцию так:
Код: pascal
1.
2.
3.
4.
function MakeFullNumber( nSerial, nNumber: Int64 ): Int64;
begin
  Result := nSerial * $FFFFFFFF + nNumber;
end;    


тогда результат совпадает, но это не вариант - функция экспортится из библиотеки, которую используют.
Пока что нашел только такое г-решение проблемы:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
function MakeFullNumber( nSerial, nNumber: Integer ): Int64;
var
  nSerial64, nNumber64: Int64;
begin
  nSerial64 := nSerial;
  nNumber64 := nNumber;
  Result := nSerial64 * $FFFFFFFF + nNumber64;
end;


Так тоже, естественно, правильно работает и я пока остановился на этом.

Но может кто подскажет - может есть какая-то настройка/деректива, которая включает кастинг "как в Делфи"? Я не нашел пока. И если кто объяснит такое поведение - тоже спасибо.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474317
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockНо может кто подскажет - может есть какая-то настройка/деректива, которая включает кастинг
"как в Делфи"?

-Mdelphi ?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474323
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockИ если кто объяснит такое поведение - тоже спасибо.
Похоже на баг компилятора. FPC 3.1.1, из транка, под Linux x64 выдаёт корректный результат, под Win32 вообще -200209.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474332
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Нет, не помогает. Ведет себя так же, как и -Mobjfpc
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474334
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexeyпод Linux x64 выдаёт корректный результат, под Win32 вообще -200209
Под win64 та же история.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474450
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock, Похоже на то, что при касте в старших разрядах оказывается мусор. Попробуй так

Код: pascal
1.
Result := (Int64(nSerial) and $FFFFFFFF) * $FFFFFFFF +( Int64(nNumber)  and $FFFFFFFF);
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474462
SimplTsar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRock... если кто объяснит такое поведение - тоже спасибо.

Код: pascal
1.
2.
3.
4.
5.
function MakeFullNumber( nSerial, nNumber: Int64 ): Int64;
begin
  Result := nSerial;
  Result := Result * $FFFFFFFF + nNumber;
end;    



Проверено FPC 3.0.2, Lazarus 1.6.4

Скорее всего "виновата" оптимизация при преобразовании типов. Достаточно посмотреть формируемый код ассембера в различных реализациях функций.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474463
SimplTsar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Описался
вместо
Код: pascal
1.
 function MakeFullNumber( nSerial, nNumber: Int64 ): Int64;


должно быть
Код: pascal
1.
 function MakeFullNumber( nSerial, nNumber: Integer ): Int64;
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474695
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_YuRock, Похоже на то, что при касте в старших разрядах оказывается мусор. Попробуй так

Код: pascal
1.
Result := (Int64(nSerial) and $FFFFFFFF) * $FFFFFFFF +( Int64(nNumber)  and $FFFFFFFF);


Да, так и есть. С принудительным обнулением старших разрядов выдает верный результат.
Страшненькая особенность, которую придется учитывать при желании перевести какой-нибудь проект на fpc.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474699
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SimplTsarСкорее всего "виновата" оптимизация при преобразовании типов. Достаточно посмотреть формируемый код ассембера в различных реализациях функций.
Мне не достаточно :) - я в ассемблере ~0. А причину проблемы определил уже _Vasilisk_.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474764
lazarus bugtracker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRockСтрашненькая особенность, которую придется учитывать при желании перевести какой-нибудь проект на fpc.
https://bugs.freepascal.org/view_all_bug_page.php
Избавите многих от страшненького.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474787
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockСтрашненькая особенность, которую придется учитывать при желании перевести какой-нибудь проект на fpc.Мне вот интересно, эта бага проявляется при касте любого типа в более широкий? Или только 32 в 64?

И еще а тупо вот так

Код: pascal
1.
2.
3.
4.
function MakeFullNumber( nSerial, nNumber: Integer ): Int64;
begin
  Result := nSerial * $FFFFFFFF + nNumber;
end;

разве не работает? Это же не Си, где тип результата определяется по операндам
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474897
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Код: pascal
1.
2.
3.
4.
function MakeFullNumber( nSerial, nNumber: Integer ): Int64;
begin
  Result := nSerial * $FFFFFFFF + nNumber;
end;


разве не работает? Это же не Си, где тип результата определяется по операндам
Не работает, я пробовал, еще и варнинг при этом (без явного каста) выдает что-то типа "Результат операции будет размером 64 бита".
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39474901
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockНе работает, я пробовал, еще и варнинг при этом (без явного каста) выдает что-то типа "Результат операции будет размером 64 бита".
А результат тот же, что и при явном касте.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39475298
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39475301
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Это же не Си, где тип результата определяется по операндам
У дельфей, кстати, если ожидается результат Int64, то один из операндов также должен быть Int64.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39475607
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyУ дельфей, кстати, если ожидается результат Int64, то один из операндов также должен быть Int64.Хм. Таки да
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure TForm1.Button1Click(Sender: TObject);
var
  LVal1: Cardinal;
  LVal2: Cardinal;
  LRes1: Int64;
  LRes2: Int64;
begin
  LVal1 := $FFFFFFFF;
  LVal2 := $FFFFFFFF;
  LRes1 := LVal1 + LVal2;
  LRes2 := Int64(LVal1) + LVal2;
  MsgFmt('Res1: %d'#13#10'Res2: %d', [LRes1, LRes2]);
end;

Код: plaintext
1.
Res1: 4294967294
Res2: 8589934590

При этом никаких хинтов и ворнингов
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39475632
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_При этом никаких хинтов и ворнингов
В доке об этом сказано:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Simple_Types_(Delphi) In general, arithmetic operations on integers return a value of type Integer, which is equivalent to the 32-bit LongInt. Operations return a value of type Int64 only when performed on one or more Int64 operands.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39475643
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock, пока остановился на этом
Код: pascal
1.
2.
3.
4.
5.
6.
function MakeFullNumber( nSerial, nNumber: Integer ): Int64;
begin
  Result := $FFFFFFFF;
  Result := Result * nSerial;
  Result := Result + nNumber;
end;  
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39475645
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock, Под win64 та же история. ?

Код: plaintext
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.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
FPC 3.0.0 (lz 1.6.2) // Result -> ok

000000010002C429 894df8                   mov    DWORD PTR [rbp-0x8],ecx
000000010002C42C 8955f0                   mov    DWORD PTR [rbp-0x10],edx
unit1.pas:32                              Result := Int64( nSerial ) * $FFFFFFFF + nNumber;
000000010002C42F 486345f8                 movsxd rax,DWORD PTR [rbp-0x8]  // ok   
000000010002C433 48baffffffff00000000     movabs rdx,0xffffffff           // ok  
000000010002C43D 480fafc2                 imul   rax,rdx         
000000010002C441 486355f0                 movsxd rdx,DWORD PTR [rbp-0x10] // ok
000000010002C445 488d0410                 lea    rax,[rax+rdx*1]
000000010002C449 488945e8                 mov    QWORD PTR [rbp-0x18],rax
unit1.pas:33                              end;


FPC 3.0.0 ( -O4 ) // Result -> ok

000000010002C427 89cb                     mov    ebx,ecx
000000010002C429 89d6                     mov    esi,edx
unit1.pas:33                              Result := Int64(nSerial) * $FFFFFFFF + nNumber;
000000010002C430 4863db                   movsxd rbx,ebx
000000010002C433 48b8ffffffff00000000     movabs rax,0xffffffff
000000010002C43D 480fafd8                 imul   rbx,rax
000000010002C441 4863f6                   movsxd rsi,esi
000000010002C444 488d0433                 lea    rax,[rbx+rsi*1]



DX 10.2  // Result -> ok 

00000000004263C8 894D20           mov [rbp+$20],ecx
00000000004263CB 895528           mov [rbp+$28],edx
Project1.dpr.12: Result := Int64( nSerial ) * $FFFFFFFF + nNumber;
00000000004263CE 48634520         movsxd rax,qword ptr [rbp+$20]          // ? qword  
00000000004263D2 C7C1FFFFFFFF     mov ecx,$ffffffff                       // ? ecx    
00000000004263D8 480FAFC1         imul rax,rcx                            
00000000004263DC 48634D28         movsxd rcx,qword ptr [rbp+$28]          // ? qword   
00000000004263E0 488D0408         lea rax,[rax+rcx]
00000000004263E4 48894508         mov [rbp+$08],rax
Project1.dpr.13: end;
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39475721
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bred eFeMYuRock, пока остановился на этом
Нет, я уже переостановился на
Код: pascal
1.
( Int64( Serial ) and $FFFFFFFF )


Мне так больше нравится - хоть понимание, зачем это написано, есть.

Bred eFeM
Код: plaintext
FPC 3.0.0 ( -O4 ) // Result -> ok

Я запускал под win64 (изначальный вариант), в результате был мусор. С вариантом [выше] стало все правильно.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39475756
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock, так у тебя and или * ?

а для x32 cpu signed($FFFFFFF) = -1 , если чё.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39475809
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bred eFeM,

ну выше ж всё описано, вточности как в 1-м посту Василиск. Вначале and, а потом результат and *.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39580133
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey https://bugs.freepascal.org/view.php?id=32046
Баг пофиксили.
...
Рейтинг: 0 / 0
арифметика в FPC - cast Integer to Int64
    #39580147
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ух ты, надо будет проверить, когда в релиз включат.
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / арифметика в FPC - cast Integer to Int64
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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