
値を10進、16進の相互変換を行いたいのですが、いまいちうまく行かずに困っています。
小さな桁数なら実現できているのですが、大きくすると変になります。
まず、10進→16進は作ることが出来ました。(計算機の16進変換と合っているので・・・)
10000081000008100000を16進にすると
8AC76CAFD29DA8A0になります。
で、今度は8AC76CAFD29DA8A0を10進にしたいのですがうまくいかないのです。
計算的にはこんな感じです。どこかおかしいですか?
0...1 * 0 = 0
A...16 * 10 = 160
8...256 * 8 = 2048
A...4096 * 10 = 40960
D...65536 * 13 = 851968
9...1048576 * 9 = 9437184
2...16777216 * 2 = 33554432
D...268435456 * 13 = 3489660928
F...4294967296 * 15 = 64424509440
A...68719476736 * 10 = 687194767360
C...1099511627776 * 12 = 13194139533312
6...17592186044416 * 6 = 105553116266496
7...281474976710656 * 7 = 1970324836974592
C...4503599627370500 * 12 = 54043195528446000
A...72057594037927900 * 10 = 720575940379279000
8...1152921504606850000 * 8 = 9223372036854800000
でこれを足すだけだと思ったのですが、
なぜかperlで一つずつ足すと10000081000008123880となります・・・
ここでexcelで検算をしてみたのですが、なぜか合いました。
0
160
2048
40960
851968
9437184
33554432
3489660928
64424509440
687194767360
13194139533312
105553116266496
1970324836974590
54043195528446000
720575940379279000
9223372036854800000
-----------------
10000081000008100000
でもおかしくないですか???1の位を手計算で足すとわかるのですが、
0になるわけが無いのです。
いったい何がどうなっているのか・・・
どうか助けてください。
No.6ベストアンサー
- 回答日時:
>This is perl, v5.8.5 built for sun4-solaris
Excelで検算したとかあったのでWindows用のPerlだと思ってたのですが
Sparc Solarisのでしたか。
であれば、CPUの違いによる可能性もあるのでもし可能なら
Windowsのか、あるいは別のOS(x86用のものがたぶん望ましい)のもので
確かめられるのならやってみてください。
あと、bigintつかってても出力に pritnf使うとまずいです。たぶん。
bigint自体の文字列化のメソッドを使ってどうにかしてください。
No.5
- 回答日時:
sakusaker7さま
> 今、5.8.8でも試してみましたが5.10.0のときと結果は同じでしたよ?
うう。何ででしょうか・・・
> 要は前回の回答でちょっと書いたように、本来15~6桁分しか正しく保持できないところに
> 10000081000008099840 という20桁の数値を食わせているからです。
BigIntを使っているのにダメなんでしょうか。
それともそもそも使い方が間違っていますでしょうか・・・
最後の足し算だけがおかしい感じなので、
10桁ずつ分けて計算して文字列として連結してしまえば
出来ることは出来るんですよね・・・
でもなんとなくwindows標準の電卓でも出来ることが
出来ないことに違和感を感じます。
>>sakusaker7さまの16進変換のアルゴリズムが私には理解できませんでした(恥
>そんなに小難しいことをやっているわけではないのですが(^^;
> こっちも説明が必要ですか?
下位の桁から
16の0乗 * 1の位
16の1乗 * 10の位
・
・
とやる方法しか知らなかったので、うーんどうやってるんだろう・・・と思いました。
あ、でも、またそれはよく勉強してみます!
いまは20桁の足し算が出来ない・・・って言うのをまずはナントカしたいです。
perlのバージョンを書いておきます。
########################################
perl -version
This is perl, v5.8.5 built for sun4-solaris
Copyright 1987-2004, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'. If you have access to the
Internet, point your browser at http://www.perl.com/, the Perl Home Page.
########################################
No.4
- 回答日時:
今、5.8.8でも試してみましたが5.10.0のときと結果は同じでしたよ?
#use feature の行は削らないとダメですが、use warnings は
#5.8.8でも使えるはずなんですが…
で、質問者さんの計算結果と比べてみると
39062816406281640
625005062500506240 ← ここまでは同じ
10000081000008099840 ← でもここで160食い違いが
ということになってますね。
たぶん、
8AC76CAFD29DA8A0
の下から二桁目の'A'を別の数字に変えると、誤差はそれに応じて変わると思います。
要は前回の回答でちょっと書いたように、本来15~6桁分しか正しく保持できないところに
10000081000008099840 という20桁の数値を食わせているからです。
詳しい説明は今はちょっと書いている余裕がないので割愛。
#時間をくれれば書きますけど
>sakusaker7さまの16進変換のアルゴリズムが私には理解できませんでした(恥
そんなに小難しいことをやっているわけではないのですが(^^;
こっちも説明が必要ですか?
No.3
- 回答日時:
sakusaker7さま、実は質問者です
(昨晩どうしても質問したかったのになぜかこのIDでログインが出来なくなり
急遽新規のIDで質問した次第です・・・)
さて、教えてもらったコードを試したところ・・・なぜか違う結果になりました。
5.8だと結果が違ってしまうようですね。
ちなみに
use warnings;
use feature ':5.10';
の2行が、そんなのない、といわれてしまうのでコメントにしました。
8
138
2220
35527
568438
9095020
145520330
2328325295
37253204733
596051275730
9536820411689
152589126587037
2441426025392602
39062816406281640
625005062500506240
10000081000008099840
なぜか160足りない!(汗
実は既にBigIntは使っているのですが・・・何かがおかしいです。
sakusaker7さまの16進変換のアルゴリズムが私には理解できませんでした(恥
なので、オーソドックスにこんな感じにしてみました。
(変数超適当です。すみません)
#!/usr/local/bin/perl
use bigint;
my $hexstr = "8AC76CAFD29DA8A0";
my $i=0;
my $hoge=0;
foreach $b (reverse (split (//,$hexstr))){
$c=hex $b;
$test=$c * 16 ** $i;
print qq($b($c) * 16 ** $i =\n);
printf qq(%25.0f\n) ,$test;
$i++;
$hoge+=$test;
}
printf "%25.0f\n", $hoge;
<実行>
0(0) * 16 ** 0 =
0
A(10) * 16 ** 1 =
160
8(8) * 16 ** 2 =
2048
A(10) * 16 ** 3 =
40960
D(13) * 16 ** 4 =
851968
9(9) * 16 ** 5 =
9437184
2(2) * 16 ** 6 =
33554432
D(13) * 16 ** 7 =
3489660928
F(15) * 16 ** 8 =
64424509440
A(10) * 16 ** 9 =
687194767360
C(12) * 16 ** 10 =
13194139533312
6(6) * 16 ** 11 =
105553116266496
7(7) * 16 ** 12 =
1970324836974592
C(12) * 16 ** 13 =
54043195528445952
A(10) * 16 ** 14 =
720575940379279360
8(8) * 16 ** 15 =
9223372036854775808
10000081000008099840
あああああ!!!やっぱり160どこかに行ってしまいます。
で、ココで気を取り直して、上の計算結果を1の位、10の位、100の位と
計算してみたところ・・・
1の位・・・50
10の位・・・75
100の位・・・72
となり、どうやら、途中の桁ごとの計算はあっているようなのです。
50
75
72
--------
8000
(100の位までの計算結果。少なくとも10の位が4ではないはず。)
合計の計算がおかしいみたいです・・・
No.2
- 回答日時:
桁が大きすぎますね。
もうちょっと小さい数字で試すといいと思います。
#!/usr/bin/perl
use strict;
use warnings;
use feature ':5.10';
my $hexstr = "8AC76CAFD29DA8A0";
my $acc = 0;
foreach my $digit (split q{}, $hexstr) {
#say $digit;
$acc = $acc * 16 + hex $digit;
#say $acc;
printf "%21.0f\n", $acc;
}
8
138
2220
35527
568438
9095020
145520330
2328325295
37253204733
596051275730
9536820411689
152589126587037
2441426025392602
39062816406281640
625005062500506240
10000081000008100000
“たまたま”正しい数字が出ていますが、精度としては15~16桁分しかないので
変換のやり方しだいで質問者さんのようにおかしな結果になることがあります。
んでまあ bigint とか使えばいいと思います。はい。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 高校 高校化学、気体、温度の有効数字 3 2023/04/02 11:39
- Excel(エクセル) エクセルのSUM関数について 4 2023/04/18 10:37
- その他(教育・科学・学問) ニュートンを㎏に変換 6 2022/12/09 10:11
- 物理学 質量とは何か? 6 2023/04/17 20:44
- ウォーキング・ランニング 10年程以上アシックスのゲルカヤノシリーズの同じサイズと足幅でランニングをして来たのですが、シリーズ 1 2022/03/27 09:29
- その他(ビジネス・キャリア) 今時の派遣社員って仕事が出来ないだけじゃなく計算も出来ないのか? 8 2022/07/22 20:53
- 化学 化学のエンタルピ変化を求め方について ある例題では各物質のモール数を換算して計算することもあり、ある 1 2022/06/20 23:22
- C言語・C++・C# キャスト演算について。 1 2023/07/15 15:28
- HTML・CSS CSS上での計算を行うためのルールについて教えてください。 3 2022/08/15 14:43
- その他(コンピューター・テクノロジー) 【Tableau Desktop】文字列から8桁の数字を日付型(yyyyMMdd)として取得 1 2023/07/31 10:17
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perl で 64ビットint を扱うには?
-
ActivePerl UTF-16の変換
-
機種依存文字定義エラーを回避...
-
Excelシート内セル記述の違いに...
-
VBAで別モジュールへの変数の受...
-
「デバイスは PRN を初期化でき...
-
ActivePerlでWindows上のパスを...
-
Excel VBAで、ユーザーフォーム...
-
エラー画面の制御?
-
サブルーチンを使った再帰的な...
-
PadWalkerのインストールの仕方
-
VBでグローバル変数を宣言するには
-
Perlモジュールインストール ta...
-
ApacheがPerlを作動してくれな...
-
msgboxの表示
-
pythonでファイル移動できません。
-
VBA This Workbookモジュール...
-
QuickTime Authoringモジュール...
-
powershellで関数名を変更する...
-
ご相談ですが。。。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
perl で 64ビットint を扱うには?
-
Perlのコードを隠蔽する
-
正規表現 \\s が、\\n に、ヒ...
-
XPathでのワイルドカード指定
-
16進変換で不具合
-
例外処理のフローチャートの記...
-
Excel VBAでリンク切れをチェッ...
-
Excel VBAで、ユーザーフォーム...
-
「デバイスは PRN を初期化でき...
-
LCD ディスプレイを Raspberry ...
-
ユーザー定義関数に#NAME?が返...
-
vba userFormのSubを標準モジュ...
-
Excel VBA 定義されたプロージ...
-
Excel VBAで、ユーザーフォー...
-
モジュールとクラスの違いって...
-
モジュールの最大数はいくつな...
-
VBAで別モジュールへの変数の受...
-
Excel VBA 『Call』で呼び出す...
-
エクセルVBAでシートモジュール...
-
VBSがコンパイルエラーになりま...
おすすめ情報