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

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
19.06.2017, 17:33
    #39474317
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
арифметика в FPC - cast Integer to Int64
YuRockНо может кто подскажет - может есть какая-то настройка/деректива, которая включает кастинг
"как в Делфи"?

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

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

Код: pascal
1.
Result := (Int64(nSerial) and $FFFFFFFF) * $FFFFFFFF +( Int64(nNumber)  and $FFFFFFFF);
...
Рейтинг: 0 / 0
19.06.2017, 21:34
    #39474462
SimplTsar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
арифметика в FPC - cast Integer to Int64
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
19.06.2017, 21:39
    #39474463
SimplTsar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
арифметика в FPC - cast Integer to Int64
Описался
вместо
Код: pascal
1.
 function MakeFullNumber( nSerial, nNumber: Int64 ): Int64;


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

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


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

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

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

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


разве не работает? Это же не Си, где тип результата определяется по операндам
Не работает, я пробовал, еще и варнинг при этом (без явного каста) выдает что-то типа "Результат операции будет размером 64 бита".
...
Рейтинг: 0 / 0
20.06.2017, 16:14
    #39474901
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
арифметика в FPC - cast Integer to Int64
YuRockНе работает, я пробовал, еще и варнинг при этом (без явного каста) выдает что-то типа "Результат операции будет размером 64 бита".
А результат тот же, что и при явном касте.
...
Рейтинг: 0 / 0
21.06.2017, 11:14
    #39475298
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
арифметика в FPC - cast Integer to Int64
...
Рейтинг: 0 / 0
21.06.2017, 11:16
    #39475301
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
арифметика в FPC - cast Integer to Int64
_Vasilisk_Это же не Си, где тип результата определяется по операндам
У дельфей, кстати, если ожидается результат Int64, то один из операндов также должен быть Int64.
...
Рейтинг: 0 / 0
21.06.2017, 16:06
    #39475607
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
арифметика в FPC - cast Integer to Int64
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
21.06.2017, 16:31
    #39475632
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
арифметика в FPC - cast Integer to Int64
_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
21.06.2017, 16:49
    #39475643
Bred eFeM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
арифметика в FPC - cast Integer to Int64
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
21.06.2017, 16:55
    #39475645
Bred eFeM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
арифметика в FPC - cast Integer to Int64
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
21.06.2017, 18:35
    #39475721
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
арифметика в FPC - cast Integer to Int64
Bred eFeMYuRock, пока остановился на этом
Нет, я уже переостановился на
Код: pascal
1.
( Int64( Serial ) and $FFFFFFFF )


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

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

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

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

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


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