喫茶XRAYトップページ

[スレッド全体
]

[10364] Cardinalの型変換返信 削除
2016/9/9 (金) 01:12:13 ny
こんにちは、知識がなく困っています。

文字列変数sに"4294967295"が入っています。
これを整数型のCardinal変数vに型変換して代入したいのですが、
v=strtoint(s);
ではできませんでした。こんな時どんな方法で型変換するのでしょうか?

どなたか教えてください。

[10366] Re:Cardinalの型変換返信 削除
2016/9/9 (金) 11:00:17 Mr.XRAY
▼ nyさん

> 文字列変数sに"4294967295"が入っています。
> これを整数型のCardinal変数vに型変換して代入したいのですが、


これ,Cardinal の最大値ですよね.
Integer の正の最大値を超えていると StrToInt は失敗するようです.
今思いつくのは以下しかありません.

>v=strtoint(s);
>ではできませんでした。


当然できません.v:=strtoint(s); ですね.
Delphi の代入は = ではなくて := です.コロンが必要です (^^;)
もしかして,C++, C#, VB ?
それとも,私の真似をして誤字脱字の類 ?

動作確認は Windows 7 U64(SP1) + Delphi XE(UP1) Pro です.

procedure TForm1.Button1Click(Sender: TObject);
var
  LText     : string;
  LCardinal : Cardinal;
begin
  LText := '4294967295';
  LCardinal := Cardinal(StrToInt64(LText));

  LText := IntToStr(LCardinal);
  MessageBox(Handle, PChar(LText), '結果', MB_ICONINFORMATION);
end;



[10368] Re2:Cardinalの型変換返信 削除
2016/9/9 (金) 14:00:48 taki
▼ Mr.XRAYさん
> ▼ nyさん
>


StrToInt64というのがあるのですね。

Cardinalは汎用型ですよね。
私のPCはWindows7 32Bitなので、Cardinalは0〜4294967295になります。
マスターのPCは64Bitなので、Cardinalはもっと大きな値まで扱えるかも?

私の32BitのPCでも試してみました。
環境 Windows7 32Bit DelphiXE4 Starter

procedure TForm1.Button7Click(Sender: TObject);
var
  v:Cardinal;
  s:string;
begin
  s := '4294967295';
  v := StrToInt64(s);
end;

結果はエラーにならず、vにも4294967295が代入されていました。
※ vはデバッグモードの「監視式」での確認ですが。

StrToIntでは-2147483648〜2147483647の値しか扱えませんが、
StrToInt64ではそれ以上の値も扱えるのですね。

StrToIntをHelp(F1)で表示した時、関連項目にStrToInt64も
あれば良かったのに…と思います。


[10370] Re3:Cardinalの型変換返信 削除
2016/9/9 (金) 14:52:46 Mr.XRAY
▼ takiさん

> 私のPCはWindows7 32Bitなので、Cardinalは0〜4294967295になります。
> マスターのPCは64Bitなので、Cardinalはもっと大きな値まで扱えるかも?


実はですね.そうはならないのでございます.
32, 64 ビットのどちらの Windows でも
Delphi で 32, 64 ビットの EXE を作成しても,
Cardinal は 32 ビットなんです.
つまり,32 ビットのコードを 64 ビットでも素直にコンパイルできます.
Integer も同じです.

問題となるのはポインタを扱うコードです.
32 ビットの EXE ではポインタのサイズは 32 bit です.
64 ビットの EXE ではポインタのサイズは 64 bit です.

そのために,NativeInt, NativeUInt が用意されています.


参考記事
[64 ビット版 Windows での使用に向けた準備]
http://ht-deko.com/tech070.html#0100


[10372] Re4:Cardinalの型変換返信 削除
2016/9/9 (金) 15:18:50 Mr.XRAY
> そのために,NativeInt, NativeUInt が用意されています.

例えば以下のコードを実行すると,
32 ビットの EXE では 32 ビットの値に,
64 ビットの EXE では 64 ビットの値になります.


procedure TForm1.Button1Click(Sender: TObject);
var
  LText  : string;
  LValue : UInt64;
begin
  LValue := High(NativeUInt);
  LText  := IntToHex(LValue, 20);

  LText := 'NativeUInt' + sLineBreak + 'Delphi XE5 32 bit EXE' + sLineBreak + LText;
  MessageBox(Handle, PChar(LText), '結果', MB_ICONINFORMATION);
end;


Windows 7 U64(SP1) で実行した結果


[10373] ありがとうございました。返信 削除
2016/9/9 (金) 21:40:37 ny
「andy」様「Mr.XRAY」様「taki」様、ありがとうございます。
v=strtoint(s);は間違いでした。v:=strtoint(s);でした。
当方の環境はWin10+ターボデルファイ2006(えっ!今だに?)でした。

LCardinal := Cardinal(StrToInt64(LText));
これでうまく変換できました。
LCardinal := StrToInt64(LText);
これでもエラーになりませんが「0」がかえってくることがありました。

NativeInt/NativeUInt
ごめんなさい。私には敷居が高い。

お陰様で解決しました。感謝!感謝です。

[10378] Re:ありがとうございました。返信 削除
2016/9/11 (日) 11:46:34 taka
▼ nyさん
> LCardinal := Cardinal(StrToInt64(LText));
> これでうまく変換できました。
> LCardinal := StrToInt64(LText);
> これでもエラーになりませんが「0」がかえってくることがありました。

型の数値の範囲を外れると0になったり想定外の数値になります。

例:Cardinal(StrToInt64('-1'));         結果: 4294967295
例:Cardinal(StrToInt64('4294967296')); 結果: 0

Cardinalは、符号なし整数なので (Cardinal  0..4294967295)
文字列から「0または正数」に変換するので以下の処理が必要です
・負の数値の文字列の処理
 エラーとするか、0にするか,Cardinalの最大値とするか
・オーバーフローの処理
 エラーとするか、0にするか,Cardinalの最大値とするか

直接 Cardinal変数に代入するのではなく
一度Int64型の変数に代入してから処理してください。

procedure TForm1.Button1Click(Sender: TObject);
var
  v : Cardinal;
  i64 : int64;
begin
  i64 := StrToInt64('4294967296');
  if (i64 < 0) then
  begin
//   raise EIntError.Create('正数を入力してください');
    i64 := 0;
  end;
  if (i64 > $FFFFFFFF) then
  begin
//   raise EIntOverflow.Create('Cardinalのサイズを超えました');
   i64 := $FFFFFFFF;
  end;
  v := Cardinal(i64);
  ShowMessage(IntToStr(v));
end;


[10382] Re2:ありがとうございました。返信 削除
2016/9/13 (火) 16:48:39 Mr.XRAY
▼ takaさん

> 直接 Cardinal変数に代入するのではなく
> 一度Int64型の変数に代入してから処理してください。


確かに.
変数の型の範囲には十分注意ですね.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82