人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHPで10進数の値を62進数に変換するプログラムを下記URLを元に作ってみたのですが、値が大きいと62進数から10進数に戻した時に正確な値にならなくて困ってます。

具体的には、

5901894628545659904 (10進数)

71YJSBTqsEC (62進数に変換)

5901894628545659718 (10進数)

と値が異なってします。
INTの最大値9223372036854775807まで正常に扱いたいのですが、何か対策はありませんでしょうか?宜しくお願いします。

参考元:
https://gist.github.com/sunaoka/6362065
http://php.net/manual/ja/function.base-convert.php

●質問者: wankodon
●カテゴリ:コンピュータ ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● sasada
●50ポイント

dohex2dec($dohex)のpowの演算が誤差を生んでるんですかねぇ

https://gist.github.com/sunaoka/6362065のfunction dohex2dec($dohex)の

 $result += $j * pow(62, $len - $i - 1);

 $result = $result * 62 + $j;

に変えてみてはいかがでしょうか。


wankodonさんのコメント
うーん、残念ながらダメでした。 ともあれ回答ありがとうございます。

2 ● a-kuma3
●250ポイント ベストアンサー

dec2dohex() の方に、演算誤差があります。
floor() への引数が浮動小数点演算になるので、そこで有効桁が足りなくなります。

以下のように変更すれば、質問の数値でも正しく動作します。

<?php
function dec2dohex($dec) {
 $hashtable = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
 $result = '';
 while($dec > 0) {
// $result = $hashtable[$dec % 62] . $result;
// $dec = floor($dec / 62);
 $mod = $dec % 62;
 $result = $hashtable[$mod] . $result;
 $dec = ($dec - $mod) / 62;
 }
 return $result;
}
?>

修正したソースで、演算の様子を var_dump すると、こうなります。

int(5901894628545659904)
string(11) "71YJSBTqsHC"
int(5901894628545659904)

元のコードでは、有効桁が途中で足りなくなるので、62進数の末尾が違ってきます。


wankodonさんのコメント
おお、これで問題なく動作しました。なるほど。 回答どうもありがとうございました。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ